Java 9 javac
มีแฟล็กใหม่--release
:
> javac --help
...
--release <release>
Compile for a specific VM version. Supported targets: 6, 7, 8, 9
แตกต่างจาก-source
และ-target
แฟล็กอย่างไร? เป็นแค่ทางลัดเพื่อ-source X -target X
?
Java 9 javac
มีแฟล็กใหม่--release
:
> javac --help
...
--release <release>
Compile for a specific VM version. Supported targets: 6, 7, 8, 9
แตกต่างจาก-source
และ-target
แฟล็กอย่างไร? เป็นแค่ทางลัดเพื่อ-source X -target X
?
คำตอบ:
ไม่ตรง
JEP 247: คอมไพล์สำหรับเวอร์ชันแพลตฟอร์มที่เก่ากว่ากำหนดอ็อพชันบรรทัดคำสั่งใหม่นี้--release
:
เราได้กำหนดตัวเลือกบรรทัดคำสั่งใหม่
--release
ซึ่งจะกำหนดค่าคอมไพลเลอร์โดยอัตโนมัติเพื่อสร้างไฟล์คลาสที่จะเชื่อมโยงกับการนำไปใช้งานของแพลตฟอร์มเวอร์ชันที่กำหนด สำหรับแพลตฟอร์มที่กำหนดไว้ล่วงหน้าในjavac
, เทียบเท่ากับ--release N
-source N -target N -bootclasspath <bootclasspath-from-N>
(เน้นของฉัน)
-source N -target N
ดังนั้นไม่มีก็จะไม่เทียบเท่ากับ เหตุผลของการเพิ่มนี้ระบุไว้ในส่วน "แรงจูงใจ":
javac
มีตัวเลือกบรรทัดคำสั่งสองรายการ-source
และ-target
ซึ่งสามารถใช้เพื่อเลือกเวอร์ชันของภาษา Java ที่คอมไพเลอร์ยอมรับและเวอร์ชันของไฟล์คลาสที่สร้างขึ้นตามลำดับ อย่างไรก็ตามโดยค่าเริ่มต้นจะjavac
คอมไพล์เทียบกับเวอร์ชันล่าสุดของแพลตฟอร์ม API โปรแกรมที่คอมไพล์แล้วจึงสามารถใช้ API ที่มีอยู่ในแพลตฟอร์มเวอร์ชันปัจจุบันโดยไม่ได้ตั้งใจเท่านั้น โปรแกรมดังกล่าวไม่สามารถทำงานบนแพลตฟอร์มเวอร์ชันเก่าได้โดยไม่คำนึงถึงค่าที่ส่งผ่านไปยัง-source
และ-target
. ตัวเลือก. นี่เป็นปัญหาในการใช้งานในระยะยาวเนื่องจากผู้ใช้คาดหวังว่าเมื่อใช้ตัวเลือกเหล่านี้พวกเขาจะได้รับไฟล์คลาสที่สามารถทำงานบนแพลตฟอร์มเวอร์ชันที่ระบุได้
ในระยะสั้นการระบุอ็อพชันซอร์สและเป้าหมายไม่เพียงพอสำหรับการคอมไพล์ข้าม เนื่องจากjavac
โดยค่าเริ่มต้นจะคอมไพล์เทียบกับแพลตฟอร์ม API ล่าสุดจึงไม่สามารถรับประกันได้ว่าจะทำงานบนเวอร์ชันเก่า คุณต้องระบุ-bootclasspath
ตัวเลือกที่สอดคล้องกับเวอร์ชันเก่าเพื่อคอมไพล์ข้ามอย่างถูกต้อง ซึ่งจะรวมถึงเวอร์ชัน API ที่ถูกต้องเพื่อรวบรวมและอนุญาตให้ดำเนินการกับเวอร์ชันเก่ากว่า เนื่องจากมักถูกลืมมากจึงตัดสินใจเพิ่มตัวเลือกบรรทัดคำสั่งหนึ่งรายการซึ่งทำทุกสิ่งที่จำเป็นเพื่อให้สามารถคอมไพล์ข้ามได้อย่างถูกต้อง
อ่านเพิ่มเติมในรายการทางไปรษณีย์และออราเคิลเอกสาร ข้อผิดพลาดเดิมถูกฟ้องที่นี่ โปรดทราบว่าตั้งแต่การรวมตัวเลือกนี้ JDK builds ได้มาพร้อมกับคำอธิบายของแพลตฟอร์ม API ของรุ่นเก่าที่กล่าวถึงในหัวข้อ "ความเสี่ยงและสมมติฐาน" นั่นหมายความว่าคุณไม่จำเป็นต้องติดตั้งเวอร์ชันเก่ากว่าบนเครื่องของคุณสำหรับการคอมไพล์ข้ามจึงจะทำงานได้
--release
ธงจะอนุมานจาก JDK ใช้สำหรับการรวบรวมซึ่งโดยทั่วไปจะแตกต่างจาก JDK คุณกำหนดเป้าหมายการใช้และ-source
-target
สิ่งนี้สามารถกัดคุณได้ในกรณีที่คุณใช้คลาส / วิธีการที่แนะนำในไม่เคย JDK จากนั้นเป็นสิ่งที่คุณกำหนดเป้าหมาย สิ่งนี้มีความละเอียดอ่อนเป็นพิเศษในกรณีที่คอมไพเลอร์เลือกวิธีโอเวอร์โหลดที่ถูกเพิ่มในเวอร์ชันที่ใหม่กว่าจากเวอร์ชันก่อนหน้าซึ่งคุณตั้งใจไว้ดังนั้นจึงทำลายความเข้ากันได้ของไบนารีอย่างเงียบ ๆ
--release X
เป็นมากกว่าทางลัด-source X -target X
เพราะ-source
และ-target
ไม่เพียงพอที่จะรวบรวมไปยังรุ่นเก่าได้อย่างปลอดภัย คุณต้องตั้งค่า-bootclasspath
สถานะที่ต้องสอดคล้องกับรุ่นเก่า (และมักจะลืมธงนี้) ดังนั้นใน Java 9 พวกเขาทำคนเดียว--release
ธงซึ่งเป็นแทนสามธง: -source
, และ-target
-bootclasspath
นี่คือตัวอย่างของการคอมไพล์ไปยัง Java 1.7:
javac --release 7 <source files>
โปรดทราบว่าคุณไม่จำเป็นต้องติดตั้ง JDK 7 บนคอมพิวเตอร์ของคุณด้วยซ้ำ JDK 9 มีข้อมูลที่จำเป็นอยู่แล้วเพื่อป้องกันไม่ให้คุณเชื่อมโยงกับสัญลักษณ์ที่ไม่มีอยู่ใน JDK 7 โดยไม่ได้ตั้งใจ