Gradle, «sourceCompatibility» против «targetCompatibility»?

130

Какая связь / разница между sourceCompatibilityи targetCompatibility? Что произойдет, если им присвоить разные значения?

Согласно документации Gradle :

sourceCompatibility"Совместимость версий Java для использования при компиляции исходного кода Java". targetCompatibilityэто «версия Java, для которой создаются классы».

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

Майк Райландер
источник

Ответы:

80

targetCompatibilityи sourceCompatibilityсопоставляет -target releaseи -source releaseв javac. Источник - это в основном уровень исходного языка, а цель - уровень генерируемого байт-кода.

Более подробную информацию можно найти в разделе кросс-компиляции javac .

Matt
источник
1
Вышеупомянутая ссылка указывает на документ для Java 7. Интересно, хотите ли вы что-нибудь вроде docs.oracle.com/en/java/javase/11/tools/… ?
Брайан Агнью,
63

Будьте осторожны при их использовании; нас укусили люди, делающие предположения.

Тот факт, что вы используете sourceCompability (или targetCompatibility) 1.5, не означает, что вы всегда можете скомпилировать свой код с JDK 1.6 и ожидать, что он будет работать под JDK 1.5. Проблема в доступных библиотеках.

Если ваш код вызывает какой-то метод, который доступен только в JDK 1.6, он все равно будет компилироваться с различными параметрами совместимости для целевой виртуальной машины. Но когда вы запустите его, он не удастся, потому что вызывающий нарушение метод отсутствует (вы получите исключение MethodNotFoundException или ClassNotFoundException).

По этой причине я всегда сравниваю параметр «Совместимость» с фактической версией Java, под которой я создаю. Если они не совпадают, я не выполняю сборку.

user1644873
источник
4
Это тонкое, но очень важное наблюдение.
Natix 08
Как вы их сравниваете?
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.
Xerus
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 = Эта опция гарантирует, что сгенерированные файлы классов будут совместимы с виртуальными машинами, указанными targetCompatibility. Обратите внимание, что в большинстве случаев значение параметра -target является значением параметра -source; в этом случае вы можете опустить опцию -target.

Файлы классов будут запускаться на цели, указанной targetCompatibility, и в более поздних версиях, но не в более ранних версиях виртуальной машины.

Джахар
источник
как определить, какие из них использует наш проект?
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версию виртуальной машины. Чтобы запустить его, например, на другой рабочей станции с более старой версией java.

Согласно: https://docs.oracle.com/en/java/javase/11/tools/javac.html

Вениамин
источник