แฟล็ก --release ในคอมไพเลอร์ Java 9 คืออะไร


89

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?


คำตอบ:


113

ไม่ตรง

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 ของรุ่นเก่าที่กล่าวถึงในหัวข้อ "ความเสี่ยงและสมมติฐาน" นั่นหมายความว่าคุณไม่จำเป็นต้องติดตั้งเวอร์ชันเก่ากว่าบนเครื่องของคุณสำหรับการคอมไพล์ข้ามจึงจะทำงานได้


มีข้อสงสัยประการหนึ่งเป็นไปได้ที่จะใช้คุณสมบัติจาก jdk 9-11 ในโค้ดและมันยังทำงานบน java runtime 8 ได้หรือไม่
Cristiano

ไม่พวกเขาจะไม่ปรากฏใน jre 8 binary
Rogue

คุณผู้ชายทำอะไรด้วย "Platform API"? เป็นสิ่งที่อยู่ในระดับไบต์โค้ดหรือไม่? หรือสิ่งที่เกี่ยวข้องกับแพลตฟอร์ม x86 หรือ OS APIs หรือไม่
Jose Cifuentes

2
@JoseCifuentes "แพลตฟอร์ม API" ที่นี่จะได้รับ JDK API รุ่นโดยไม่ต้อง--releaseธงจะอนุมานจาก JDK ใช้สำหรับการรวบรวมซึ่งโดยทั่วไปจะแตกต่างจาก JDK คุณกำหนดเป้าหมายการใช้และ-source -targetสิ่งนี้สามารถกัดคุณได้ในกรณีที่คุณใช้คลาส / วิธีการที่แนะนำในไม่เคย JDK จากนั้นเป็นสิ่งที่คุณกำหนดเป้าหมาย สิ่งนี้มีความละเอียดอ่อนเป็นพิเศษในกรณีที่คอมไพเลอร์เลือกวิธีโอเวอร์โหลดที่ถูกเพิ่มในเวอร์ชันที่ใหม่กว่าจากเวอร์ชันก่อนหน้าซึ่งคุณตั้งใจไว้ดังนั้นจึงทำลายความเข้ากันได้ของไบนารีอย่างเงียบ ๆ
Oliver Gondža

30

--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 โดยไม่ได้ตั้งใจ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.