JDK, JRE совместимость JAR
Я немного разбираюсь в исходной и двоичной совместимости JDK и JRE (например, this и this), но не уверены в следующей ситуации:
У меня есть приложение, которое скомпилировано с использованием JDK5 и работает на JRE6. Он использует некоторые библиотеки (банки), которые также скомпилированы с использованием JDK5.
Теперь я хочу скомпилировать свое приложение с помощью JDK6. Какие новые проблемы могут возникнуть во время выполнения в таком случае (в частности, в совместимости с "старыми" банками)? Должен ли я полностью повторять заявку (касаться каждой библиотеки) или полагаться на обещанную совместимость JDK/JRE?
Ответы
Ответ 1
Обычно никаких проблем не возникает, если вы установите для параметра компилятора JDK6 использование совместимости с исходным кодом 1.5. Однако иногда это не всегда так.
Помню один раз при компиляции 1.4 кода с 1.5 компилятором (с использованием 1.4 совместимости). Банки, где нормально (1.4 двоичный уровень), но приложение разбилось из-за смешного преобразования.
Мы использовали число BigDecimal, передающее целое число как аргумент конструктору. версия 1.4 имела только конструктор из double
, но 1.5 version имели оба, конструкторы int
и double
. Поэтому, когда компиляция с 1.4 компилятором сделала автоматическое преобразование от int
до double
, но с компилятором 1.5 он проверил существование конструктора int
и не понял этого преобразования. Затем при использовании идеального бинарного кода на 1.4 JRE программа разбилась с помощью NoSuchMethodException
.
Я должен признать, что это был странный случай, но это один из тех случаев, когда логика не работает. Поэтому мой совет: если вы планируете компилировать более старые версии JRE, попробуйте использовать целевую версию JDK, когда это возможно.
Ответ 2
До тех пор, пока вы не измените свой код и не добавите новые функции Java 6, проблем не должно быть.
Что касается других банок, то проблем вообще не должно быть.
JDK всегда поддерживает обратную совместимость.
Ответ 3
Совместимость в основном работает. Я бы не ожидал, что возникнет какая-либо проблема, возникшая в стороне от различных предупреждений, например. не используя дженерики. Возможно, некоторые едва ли используемые API были устаревшими, но я предполагаю, что они оставлены на месте, просто отмечены как устаревшие.
Просто попробуйте, если он скомпилируется, вы должны быть в порядке.
Ключевым аспектом дизайна Java, к сожалению, является полная обратная совместимость.
Существует очень мало исключений, когда обратная совместимость не сохранялась; наиболее заметно, что Eclipse страдал, когда алгоритм сортировки был изменен с устойчивого на нестабильный алгоритм сортировки (порядок объектов, которые идентичны идентично, больше не сохранялся); но это никогда не было частью спецификации Java, но ошибка в Eclipse.
Это печально, потому что было несколько плохих выборов, которые теперь нельзя изменить. Iterator
не должен был иметь функцию remove()
в API, Vector
не должен был быть синхронизирован (решается с помощью ArrayList
сейчас), StringBuffer
не должен быть синхронизирован, следовательно StringBuilder
. String
должен, вероятно, быть интерфейсом, а не классом, чтобы разрешить, например, 8-битные строки, 32-разрядные строки - CharSequence
- лучший интерфейс строки, но слишком много методов не принимают CharSequence
и требуют возврата String
. Observable
также должен быть интерфейсом: вы не можете сделать подкласс наблюдаемым с этим API. Назвать несколько. Но из-за обратной совместимости они не могут быть исправлены до тех пор, пока, возможно, JDK-модуляция (в какой момент некоторые из них могут по крайней мере исчезнуть в модуль donotuse...).
Конечно, у вас уже должно быть тысячи модульных тестов, которые помогут вам протестировать новый JDK...: -)