Могут ли разные обновления JDK создавать разные байт-коды Java?

Гипотетический сценарий:

У меня есть проект, уровень соответствия которого указан в 1.5. Теперь я скомпилирую этот проект с двумя разными JDK: сначала с JDK 6 Update 7, а затем с JDK 6 Update 20.

Разделяют ли эти два разных JDK разные байтовые коды Java, хотя они отличаются только их версией обновления?

Ответ 1

Сгенерированный код обычно отличается только в случае исправлений ошибок компилятора.

Однако в JLS не указывается сопоставление 1:1 из исходного кода в сгенерированный байт-код, поэтому вы не должны полагаться на тот же самый байт-код, который должен быть сгенерирован.

Ответ 2

Нет ничего, что могло бы помешать различным версиям генерировать разные байт-коды, если это соответствует поведению, указанному в JLS. JLS оставляет много деталей реализации, чтобы варьироваться от одной реализации к другой.

Ответ 3

Пусть ответьте с другой стороны: нет никакой гарантии, что любые две версии jdk производят идентичный байтовый код. Таким образом, вы можете ожидать различия в целом.

Ответ 4

Почему на Земле кто-то пойдет на проблему с выпуском обновления набора для разработки, если он не приведет к изменению байтового кода, по крайней мере, в некоторых случаях? Я сильно сомневаюсь, что кто-то сделает это только для обновления документации.

Ответ 5

Байт-код может немного отличаться, но об этом не о чем беспокоиться, поскольку он будет по-прежнему совместим.

То, что действительно будет выполнено, зависит от JIT.

Ответ 6

Компилятор, например JDK 6 Update 7, может выводить несколько другой байт-код, чем компилятор JDK 6 Update 20, но поскольку он и Java 6, файлы классов будут полностью совместимы - вы сможете запускать код, скомпилированный с помощью Обновите 20 обновлений 7 без проблем.

Между основными версиями Java (например, Java 5 и Java 6) могут быть изменения, поэтому код, скомпилированный в более новой версии, не будет работать в старой версии. Например, для Java 7 скорее всего будет новая инструкция, invokedynamic. Файлы классов, содержащие эту инструкцию, не будут запускаться на старых версиях Java.

Такие большие изменения, однако, никогда не выполняются между версиями обновлений.

Ответ 7

Как обычно для разных компиляторов, это также в случае Java: результат должен быть таким же, но способ, которым он достигается, может быть (с точки зрения байт-кодов) другим. из-за оптимизации или аналогичного. JVM - это машина на основе стека; следующее является мнимым примером (я не знаю jnm-мнемоники для инструкций операций)

push 10
push 20
add
push 19
push 1
add
push 10
add

Они дают одинаковый результат, но сгенерированные bytecodes разные (первый слегка оптимизирован, второй полностью "не оптимизирован", третий вариант может быть push 30, так как мы добавляем известные (вероятно, в compiletime) константы). Это простой случай, но сложный случай можно легко построить.

Ответ 8

Если вы скомпилируете разные версии JDK, я бы посоветовал использовать целевой параметр javac. В противном случае вы не сможете запустить банку со старым JDK.

Вы также можете использовать опцию source для javac, чтобы разработчик не использовал классы/методы, добавленные в более позднем JDK.