Я видел параметры компиляции, как обсуждалось в Какие дистрибутивы JDK могут запускать` javac -source 1.6 -target 1.5`?. Я понимаю отдельные варианты источника и цели. Я не понимаю, почему исходная версия выше, чем целевая версия. Компиляция кода для старых целей имеет смысл. Но в этом случае, почему мы просто не используем источник исходной цели, которую мы хотим запустить на
Параметры источника javac и целевые параметры
Ответ 1
Java обратно совместима. Вы используете опцию -source, чтобы указать версию java, используемую для компиляции, и используйте параметр -target, чтобы указать самую низкую версию java для поддержки. например. Если я укажу цель в 1,4, то моя программа не сможет работать на java 1.3 или ниже. более подробную информацию см. в следующей документации javac . особенно раздел Опции перекрестной компиляции
Ответ 2
- source: версия, которую должен выполнить ваш исходный код.
- target: самая старая версия JRE, которую вы хотите поддержать.
Обязательно также установите bootclasspath, чтобы убедиться, что ваша программа будет работать на старых виртуальных машинах.
Из javac
документация:
Пример кросс-компиляции
Следующий пример использует javac для компиляции кода, который будет работать на 1.6 VM.
C\:>javac -source 1.6 -target 1.6 -bootclasspath C:\jdk1.6.0\lib\rt.jar -extdirs "" OldCode.java
Параметр
-source 1.6
указывает, что для компиляцииOldCode.java
используется версия 1.6 (или 6) языка программирования Java. Опция-target 1.6
гарантирует, что сгенерированные файлы классов будут совместимы с 1.6 VM. Обратите внимание, что в большинстве случаев значение параметра-target
является значением параметра-source
; в этом примере вы можете опустить параметр-target
.Вы должны указать опцию
-bootclasspath
, чтобы указать правильную версию классов начальной загрузки (библиотекаrt.jar
). Если нет, компилятор генерирует следующее предупреждение:C:\>javac -source 1.6 OldCode.java warning: [options] bootstrap class path not set in conjunction with -source 1.6
Если вы не укажете правильную версию классов начальной загрузки, компилятор будет использовать старые правила языка (в этом примере он будет использовать версию 1.6 языка программирования Java) в сочетании с новыми классами начальной загрузки, что может привести к которые не работают на более старой платформе (в данном случае Java SE 6), потому что ссылка на несуществующие методы может быть включена.
Ответ 3
Питер Ценг упоминает много ключевых моментов, которые нужно запомнить во время компиляции. На самом деле даже я столкнулся с подобной проблемой когда-нибудь и хочу поделиться основными причинами многих проблем.
У меня был исходный код, который должен был скомпилировать и сделать его совместимым (-source и -target) Java '1.8'. Сам код имел
- Множество символов товарного знака, следовательно, я оказался в непризнанных персонажах (мне нужно было настроить настройки кодировки IntelliJ Idea).
- Много изменений в пакете
java.sql.*
- Использование большого количества сторонних библиотек. Освободите меня от ужаса объяснения трудности отладки там и бла-бла-бла.
После определенных изменений я закончил с кодом, в котором было одинаковое количество тестовых примеров JUnit для запуска. В конце концов я столкнулся с java.lang.VerifyError
. Я был потрясен, когда понял, что такая ошибка возникает, когда я компилирую и запускаю код в разных библиотеках/средах (что не так).
То, что я почти пропустил, состояло в том, что для того, чтобы удостовериться в том, что тесты должны были выполняться в изолированной среде, Junit и его тестовые примеры, выполняемые в отдельной разветвленной VM
<target name="runJunit">
<junit printonsummary="on"
haltonfailure="off"
fork="true"
forkmode="once">
<formatter />
<batchtest />
<classpath />
</junit>
</target>
Это, очевидно, будет растягиваться как отдельный процесс и действовать как автономное приложение при исполнении. Несмотря на то, что среда IDE поддерживает оба процесса синхронно, JVM довольно изолированы.
После Java 1.7 Oracle ввел более строгую проверку и немного изменил формат класса - чтобы содержать карту стека, используемую для проверки правильности кода. Исключением, которое я видел, было то, что у какого-то метода нет допустимой карты стека. В конце концов я попытался включить множество опций JVM, чтобы настроить настройки, но тщетно.
<jvmarg value="bootclasspath:{env.JAVA_HOME}\jre\bin\rt.jar" prefix="-X"/>
ничего не получилось. Единственная работа вокруг заключалась в том, чтобы включить
<jvmarg value=":UseSplitVerifier" prefix="-XX"/> in Java 1.7 to allow only nominal byte code verification.
Поскольку это было снято в Java 1.8, единственным вариантом было использование
<jvmarg value="-noverify"/>
- Нитин
Ответ 4
JDK1.8 больше не будет поддерживать -source и -target меньше 1.6
"c:\Program Files\Java\jdk1.8.0_121\bin\javac.exe" -source 1.3 HelloWorld.java
warning: [options] bootstrap class path not set in conjunction with -source 1.3
warning: [options] source value 1.3 is obsolete and will be removed in a future release
warning: [options] target value 1.4 is obsolete and will be removed in a future release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
4 warnings