Gradle, “sourceCompatibility” vs “targetCompatibility”?


130

Яке відношення / різниця між sourceCompatibilityта targetCompatibility? Що відбувається, коли вони встановлені на різні значення?

Відповідно до документації Gradle :

sourceCompatibilityє "Сумісність версії Java, яку слід використовувати при компілюванні джерела Java." targetCompatibilityце "версія Java для генерації класів для."

Я розумію, що targetCompatibilityгенеруватиме байт-код Java, сумісний із конкретною версією Java, це підмножина функціональності sourceCompatibility?

Відповіді:


80

targetCompatibilityі sourceCompatibilityкарти до -target releaseі -source releaseв javac. В основному джерело - це рівень мови джерела, а цільовим є рівень генерованого байтового коду.

Більш детально можна ознайомитися в розділі компіляції javac cross .


1
Наведене вище посилання вказує на doc для Java 7. Цікаво, чи хочете ви щось на зразок docs.oracle.com/en/java/javase/11/tools/… ?
Брайан Агнеу

63

Будьте обережні, використовуючи ці; нас покусали люди, які роблять припущення.

Тільки тому, що ви використовуєте sourceCompability (або targetCompatibility) 1,5, не означає, що ви завжди можете компілювати свій код з JDK 1.6 і очікувати, що він буде працювати під JDK 1.5. Проблема - наявні бібліотеки.

Якщо ваш код зателефонує до якогось методу, який доступний лише в JDK 1.6, він все ще буде компілюватися з різними варіантами сумісності для цільової VM. Але коли ви запустите його, він не вдасться, оскільки методу правопорушення немає (ви отримаєте MethodNotFoundException або ClassNotFoundException).

З цієї причини я завжди порівнюю налаштування сумісності з фактичною версією Java, під якою будуюсь. Якщо вони не збігаються, я провалюю збірку.


4
Це тонке, але дуже важливе спостереження.
Natix

Як ви їх порівнюєте?
zero01alpha

Чому не виходить збірка? Опція "bootstrap classpath" надана саме для пом'якшення цієї проблеми. Ви завжди можете використовувати належний завантажувальний інструмент, і він повинен працювати чудово.
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.
Ксерус

2
Оскільки у Java 9 тепер існує нова javacопція, --releaseпризначена для вирішення цієї проблеми, лише дозволяючи використовувати API, доступний у вказаній версії Java. Докладніше про це дивіться stackoverflow.com/a/43103038/4653517
Джеймс

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, ви не можете використовувати лямбда-вираз, який є новою функцією в 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. Для того, щоб запустити його, наприклад, на інших робочих станціях зі старшою версією Java.

Відповідно до: https://docs.oracle.com/en/java/javase/11/tools/javac.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.