Является ли байт-код Java всегда совместимым с пересылкой?

Я понимаю, что байт-код, сгенерированный версией JDK X, гарантированно будет работать на JVM Y при условии, что Y >= X.

Подходит ли это для всех версий JDK/JVM? i.e Справедливо ли ожидать, что файлы классов, сгенерированные JDK 1, будут работать на JVM 11?

Ссылка на спецификации JVM, Руководство по совместимости JDK 8 и Java 11 JSR Не удалось найти там точного ответа.


person Sarvesh    schedule 23.03.2018    source источник
comment
Ну, мы не можем заглянуть в будущее, но пока да.   -  person Kayaman    schedule 23.03.2018


Ответы (2)


Сам байт-код должен работать в будущих версиях. До сих пор это верно, но никто не знает, будет ли это верно для всего будущего.

Что меняется и может сломать вашу программу, так это изменения в API. Устаревшие API могут исчезнуть в будущем, и тогда ваша программа больше не будет работать и может выдать java.lang.NoSuchMethodError при ссылке на такой метод.

person Uwe Plonus    schedule 23.03.2018
comment
Ссылка на любую спецификацию/документ, в которой обсуждается совместимость байт-кода, была бы отличной. - person Sarvesh; 23.03.2018
comment
@SarveswaranMeenakshiSundaram Может проверить это...? wiki.openjdk.java.net/display/csr/Kinds+of+ Совместимость - person Ray Eldath; 12.08.2019

Байт-код Java не поддерживает прямую совместимость, виртуальные машины JVM обратно совместимы. Разница между этими свойствами заключается в том, что любая будущая JVM может отказаться от обратной совместимости с определенной более старой версией байт-кода.

Байт-код Java был разработан таким образом, что такое сокращение требуется редко, но уже было преднамеренное ограничение обратной совместимости. Начиная с Java 8, поддержка другой семантики invokespecial в Java 1.0 прекращена. Как JVM Спецификация §4.1 гласит:

Флаг ACC_SUPER указывает, какая из двух альтернативных семантик должна быть выражена инструкцией invokespecial (§invokespecial), если он присутствует в этом классе или интерфейсе. Компиляторы набора инструкций виртуальной машины Java должны установить флаг ACC_SUPER. В Java SE 8 и более поздних версиях виртуальная машина Java считает, что флаг ACC_SUPER установлен в каждом файле class, независимо от фактического значения флага в файле class и версии файла class.

Флаг ACC_SUPER существует для обратной совместимости с кодом, скомпилированным более старыми компиляторами для языка программирования Java. В выпусках JDK до 1.0.2 компилятор генерировал access_flags, в котором флаг, теперь представляющий ACC_SUPER, не имел назначенного значения, а реализация виртуальной машины Java Oracle игнорировала флаг, если он был установлен.

Это не означает, что ранний код Java 1.0 вообще не работает. Сломается только код, основанный на устаревшей и теперь неподдерживаемой семантике invokespecial той ранней версии.

Другое изменение заключается в том, что инструкции jsr и ret были удалены¹, однако это изменение связано с более новыми версиями файлов классов, поэтому эти инструкции по-прежнему поддерживаются для более старых версий файлов классов, поэтому они не нарушают существующий код. Но это может быть причиной того, что будущие JVM прекратят поддержку этих старых версий.


¹ спецификация JVM §4.9. 1:

Если номер версии файла class равен 51.0 или выше, то ни код операции jsr, ни код операции jsr_w не могут отображаться в массиве code.

Инструкция ret не упоминалась, но без инструкций jsr она не работает.

person Holger    schedule 23.03.2018