Gradle,“ sourceCompatibility” กับ“ targetCompatibility”?


130

อะไรคือความสัมพันธ์ / ความแตกต่างระหว่างsourceCompatibilityและtargetCompatibility? จะเกิดอะไรขึ้นเมื่อตั้งค่าเป็นค่าต่างๆ

ตามเอกสาร Gradle :

sourceCompatibilityคือ "ความเข้ากันได้ของเวอร์ชัน Java ที่จะใช้เมื่อรวบรวมซอร์ส Java" targetCompatibilityคือ "เวอร์ชัน Java สำหรับสร้างคลาสสำหรับ"

ความเข้าใจของฉันคือtargetCompatibilityจะสร้าง java bytecode ที่เข้ากันได้กับ Java เวอร์ชันเฉพาะนี่เป็นส่วนย่อยของฟังก์ชันการทำงานของsourceCompatibilityหรือไม่?

คำตอบ:


80

targetCompatibilityและsourceCompatibilityแผนที่ไปยัง-target releaseและ-source releaseใน javac Source เป็นระดับภาษาต้นทางและเป้าหมายคือระดับของ bytecode ที่สร้างขึ้น

รายละเอียดเพิ่มเติมสามารถพบได้ใน javac ข้ามส่วนการรวบรวม


1
ลิงค์ด้านบนชี้ไปที่ doc สำหรับ Java 7 ฉันสงสัยว่าคุณต้องการอะไรเช่นdocs.oracle.com/en/java/javase/11/tools/… ?
Brian Agnew

63

ระมัดระวังเมื่อคุณใช้สิ่งเหล่านี้ เราเคยถูกกัดโดยคนที่ตั้งสมมติฐาน

เพียงเพราะคุณใช้ sourceCompability (หรือ targetCompatibility) ที่ 1.5 ไม่ได้หมายความว่าคุณจะสามารถคอมไพล์โค้ดของคุณด้วย JDK 1.6 ได้ตลอดเวลาและคาดว่าจะทำงานภายใต้ JDK 1.5 ปัญหาคือไลบรารีที่มีอยู่

หากโค้ดของคุณเกิดการเรียกใช้เมธอดบางอย่างที่มีเฉพาะใน JDK 1.6 เท่านั้นโค้ดจะยังคงคอมไพล์กับตัวเลือกความเข้ากันได้ต่างๆสำหรับ VM เป้าหมาย แต่เมื่อคุณเรียกใช้มันจะล้มเหลวเนื่องจากไม่มีวิธีการละเมิด (คุณจะได้รับ MethodNotFoundException หรือ ClassNotFoundException)

ด้วยเหตุนี้ฉันจึงเปรียบเทียบการตั้งค่าความเข้ากันได้กับเวอร์ชัน Java จริงที่ฉันกำลังสร้างอยู่เสมอ หากไม่ตรงกันแสดงว่าฉันสร้างไม่สำเร็จ


4
นี่เป็นข้อสังเกตที่ละเอียดอ่อน แต่สำคัญมาก
Natix

คุณเปรียบเทียบได้อย่างไร?
zero01alpha

ทำไมคุณถึงล้มเหลวในการสร้าง ตัวเลือก "bootstrap classpath" มีไว้เพื่อบรรเทาปัญหานี้เท่านั้น คุณสามารถใช้ bootstrap ที่เหมาะสมได้ตลอดเวลาและควรใช้งานได้ดี
Codebender

6
if(JavaVersion.current() != JavaVersion.VERSION_1_8) throw new GradleException("This project requires Java 8, but it's running on "+JavaVersion.current())นี่คือวิธีที่ฉันจัดการปัญหานี้ในส่วนเริ่มต้นของไฟล์ build.gradle
Xerus

2
เนื่องจาก Java 9 มีjavacตัวเลือกใหม่--releaseสำหรับแก้ไขปัญหานี้โดยอนุญาตให้ใช้ API ที่มีอยู่ในเวอร์ชัน Java ที่ระบุเท่านั้น ดูข้อมูลเพิ่มเติมได้ที่stackoverflow.com/a/43103038/4653517
James Mudd

35

sourceCompatibility = ระบุเวอร์ชันของภาษาโปรแกรม Java ที่ใช้ในการคอมไพล์ไฟล์. java เช่น sourceCompatibility 1.6 = ระบุว่าเวอร์ชัน 1.6 ของภาษาโปรแกรม Java ถูกใช้เพื่อคอมไพล์ไฟล์. java

ตามค่าเริ่มต้น sourceCompatibility = "เวอร์ชันของ JVM ปัจจุบันที่ใช้อยู่" และ targetCompatibility = sourceCompatibility

targetCompatibility = อ็อพชันช่วยให้มั่นใจได้ว่าไฟล์คลาสที่สร้างขึ้นจะเข้ากันได้กับ VM ที่ระบุโดย targetCompatibility โปรดทราบว่าในกรณีส่วนใหญ่ค่าของอ็อพชัน -target คือค่าของอ็อพชัน -source ในกรณีนี้คุณสามารถละเว้นตัวเลือก -target

ไฟล์คลาสจะทำงานบนเป้าหมายที่ระบุโดย targetCompatibility และในเวอร์ชันที่ใหม่กว่า แต่ไม่ใช่บน VM เวอร์ชันก่อนหน้า


เราจะทราบได้อย่างไรว่าโครงการของเราใช้โครงการใด
isJulian00

0

ในความคิดของฉัน "sourceCompatibility" หมายถึงคุณลักษณะที่คุณสามารถใช้ในซอร์สโค้ดของคุณได้ตัวอย่างเช่นหากคุณตั้งค่า sourceCompatibility เป็น 1.7 คุณจะไม่สามารถใช้ lambda expression ซึ่งเป็นคุณลักษณะใหม่ใน java 8 แม้ว่าคุณจะเป็นเวอร์ชัน jdk ก็ตาม 1.8
สำหรับ "targetCompatibility" หมายถึงเวอร์ชันของ jre ที่ไฟล์คลาสที่สร้างขึ้นสามารถรันได้หากคุณตั้งค่าเป็น 1.8 มันอาจทำงานบน jdk 1.7 ไม่สำเร็จ แต่โดยปกติจะสามารถทำงานบน jdk เวอร์ชันที่สูงกว่าได้


0

นี่คือแฟล็กสำหรับคำสั่ง javac

javac [options] [sourcefiles]

Options:
...
-source release - Specifies the version of source code accepted.
...
-target release - Generates class files for a specific VM version.
...

กล่าวอีกนัยหนึ่ง: คุณเขียนรหัสในไฟล์ sourceเวอร์ชันและคอมไพล์คลาสของคุณเป็นtargetเวอร์ชัน VM เพื่อเรียกใช้งานเช่นบนเวิร์กสเตชันอื่นที่มีจาวาเวอร์ชันเก่ากว่า

อ้างอิงจาก: https://docs.oracle.com/en/java/javase/11/tools/javac.html

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