Gradle, "sourceCompatibility" vs "targetCompatibility"?

130

Apa hubungan / perbedaan antara sourceCompatibilitydan targetCompatibility? Apa yang terjadi ketika mereka diatur ke nilai yang berbeda?

Menurut dokumentasi Gradle :

sourceCompatibilityadalah "Kompatibilitas versi Java untuk digunakan saat kompilasi sumber Java." targetCompatibilityadalah "Versi Java untuk menghasilkan kelas untuk."

Pemahaman saya adalah bahwa targetCompatibilityakan menghasilkan bytecode java yang kompatibel dengan versi Java tertentu, apakah ini bagian dari fungsi sourceCompatibility?

Mike Rylander
sumber

Jawaban:

80

targetCompatibilitydan sourceCompatibilitypeta ke -target releasedan -source releasedi javac. Source pada dasarnya adalah level bahasa sumber dan target adalah level dari bytecode yang dihasilkan.

Rincian lebih lanjut dapat ditemukan di javac bagian kompilasi silang .

Mat
sumber
1
Tautan di atas menunjuk ke doc untuk Java 7. Saya ingin tahu apakah Anda menginginkan sesuatu seperti docs.oracle.com/en/java/javase/11/tools/… ?
Brian Agnew
63

Hati-hati saat Anda menggunakan ini; kami telah digigit oleh orang yang membuat asumsi.

Hanya karena Anda menggunakan sourceCompability (atau targetCompatibility) 1,5 tidak berarti Anda selalu dapat mengkompilasi kode Anda dengan JDK 1.6 dan mengharapkannya bekerja di bawah JDK 1.5. Masalahnya adalah perpustakaan yang tersedia.

Jika kode Anda memanggil beberapa metode yang hanya tersedia di JDK 1.6, kode itu masih akan dikompilasi dengan berbagai opsi Kompatibilitas untuk VM target. Tetapi ketika Anda menjalankannya, itu akan gagal karena metode menyinggung tidak hadir (Anda akan mendapatkan MethodNotFoundException atau ClassNotFoundException).

Untuk alasan ini, saya selalu membandingkan pengaturan Kompatibilitas dengan versi Java yang sebenarnya sedang saya buat. Jika mereka tidak cocok, saya gagal membangun.

pengguna1644873
sumber
4
Ini adalah pengamatan yang halus, tetapi sangat penting.
Natix
Bagaimana Anda membandingkannya?
zero01alpha
Mengapa Anda gagal membangun? Opsi "bootstrap classpath" diberikan hanya untuk mengurangi masalah ini. Anda selalu dapat menggunakan bootstrap yang tepat dan itu seharusnya bekerja dengan baik.
Codebender
6
if(JavaVersion.current() != JavaVersion.VERSION_1_8) throw new GradleException("This project requires Java 8, but it's running on "+JavaVersion.current())Ini adalah bagaimana saya menyelesaikan masalah ini, tepat di awal file build.gradle.
Xerus
2
Karena Java 9 sekarang ada javacopsi baru yang --releasedimaksudkan untuk mengatasi masalah ini, dengan hanya mengizinkan penggunaan API yang tersedia di versi Java yang ditentukan. Untuk informasi lebih lanjut tentang ini, lihat stackoverflow.com/a/43103038/4653517
James Mudd
35

sourceCompatibility = menentukan bahwa versi bahasa pemrograman Java digunakan untuk mengkompilasi file .java . misalnya sourceCompatibility 1.6 = menentukan bahwa versi 1.6 dari bahasa pemrograman Java digunakan untuk mengkompilasi file .java .

Secara default sourceCompatibility = "versi JVM saat ini sedang digunakan" dan targetCompatibility = sourceCompatibility

targetCompatibility = Opsi memastikan bahwa file kelas yang dihasilkan akan kompatibel dengan VM yang ditentukan oleh targetCompatibility. Perhatikan bahwa dalam kebanyakan kasus, nilai opsi -target adalah nilai opsi -sumber; dalam hal ini, Anda dapat menghilangkan opsi -target.

File kelas akan berjalan pada target yang ditentukan oleh targetCompatibility dan pada versi yang lebih baru, tetapi tidak pada versi VM yang lebih lama

A Jakhar
sumber
bagaimana kita mencari tahu mana yang digunakan proyek kita?
isJulian00
0

Menurut pendapat saya, "sourceCompatibility" berarti fitur apa yang dapat Anda gunakan dalam kode sumber Anda. Misalnya, jika Anda mengatur sourceCompatibility ke 1.7, maka Anda tidak dapat menggunakan ekspresi lambda yang merupakan fitur baru di java 8 meskipun Anda versi jdk adalah 1.8.
Adapun "targetCompatibility", itu berarti versi jre mana file kelas yang dihasilkan dapat dijalankan, jika Anda mengaturnya ke 1.8, itu mungkin tidak berjalan dengan sukses pada jdk 1.7, tetapi biasanya dapat berjalan pada versi jdk yang lebih tinggi.

haoyu wang
sumber
0

Ini adalah flag untuk perintah javac.

javac [options] [sourcefiles]

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

Dengan kata lain: Anda menulis kode dalam sourceversi dan mengkompilasi kelas Anda ke targetversi VM. Untuk menjalankannya misalnya pada workstation lain dengan versi java yang lebih lama.

Menurut: https://docs.oracle.com/en/java/javase/11/tools/javac.html

Benjamin
sumber