Gradle, "sourceCompatibility" против "targetCompatibility"?
Какая связь / разница между sourceCompatibility
а также targetCompatibility
? Что происходит, когда для них установлены разные значения?
Согласно документации Gradle:
sourceCompatibility
"Совместимость версий Java для использования при компиляции исходного кода Java".targetCompatibility
это "Java-версия для создания классов."
Я понимаю, что targetCompatibility
будет генерировать Java-байт-код, который совместим с конкретной версией Java, является ли это подмножеством функций sourceCompatibility
?
6 ответов
Это отображается на javac - см. раздел кросс-компиляции - source - это, в основном, уровень исходного языка, а target - уровень генерируемого байт-кода.
Будьте осторожны, когда используете их; нас укусили люди, делающие предположения.
Тот факт, что вы используете sourceCompability (или targetCompatibility) со значением 1,5, не означает, что вы всегда можете скомпилировать свой код с JDK 1.6 и ожидать, что он будет работать под JDK 1.5. Проблема в доступных библиотеках.
Если ваш код вызывает некоторый метод, который доступен только в JDK 1.6, он все равно будет компилироваться с различными параметрами совместимости для целевой виртуальной машины. Но когда вы запустите его, он потерпит неудачу, потому что вызывающий метод отсутствует (вы получите исключение MethodNotFoundException или ClassNotFoundException).
По этой причине я всегда сравниваю параметр Compatibility с фактической версией Java, под которой я строю. Если они не совпадают, я проваливаю сборку.
sourceCompatibility = указывает, что версия языка программирования Java будет использоваться для компиляции файлов .java. Например, sourceCompatibility 1.6 = указывает, что версия 1.6 языка программирования Java будет использоваться для компиляции файлов .java.
По умолчанию sourceCompatibility = "версия текущей используемой JVM" и targetCompatibility = sourceCompatibility
targetCompatibility = Опция гарантирует, что сгенерированные файлы классов будут совместимы с виртуальными машинами, указанными в targetCompatibility. Обратите внимание, что в большинстве случаев значение параметра -target является значением параметра -source; в этом случае вы можете опустить опцию -target.
Файлы классов будут выполняться на цели, указанной в targetCompatibility и более поздних версиях, но не на более ранних версиях виртуальной машины.
Было дано много хороших объяснений того, для чего подходит vs, и еще одну хорошую статью можно найти здесь Gradle: sourceCompatiblity vs targetCompatibility. Но вместо vs я бы предложил использовать Gradletoolchain
(см. Toolchains для проектов JVM ), который делает или настраивает устаревшие и гарантирует, что языковые функции (sourceCompatibility
), байт-код (targetCompatibility
) и Java-API/-библиотеки (release
) будет соответствовать версии Java. (Единственный недостаток в том, что поддержка IDE еще не полностью установлена, но уже в пути).
На мой взгляд, "sourceCompatibility" означает, какую функцию вы можете использовать в своем исходном коде. Например, если вы установите sourceCompatibility на 1,7, то вы не сможете использовать лямбда-выражение, которое является новой функцией в java 8, даже если ваша версия jdk 1.8.
Что касается "targetCompatibility", это означает, что на какой версии jre сгенерированный файл класса можно запустить, если вы установите его на 1.8, он может не работать успешно на jdk 1.7, но обычно он может работать на более поздней версии jdk.
Это флаги для команды 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