Java是向后兼容的,但是当我们将jdk从1.6升级到1.8时,为什么我们需要升级许多库?
最近,我在一个Java项目中将Jdk版本从1.6
升级到1.8
。 但是有一些编译或运行时错误,所以我必须升级一些库:
- gradle:
1.9
到1.10
- 弹簧:
3.x
到4.x
这是因为他们使用的是早期版本的ASM,但仅支持5.x
版本的jdk 1.8
Java表示它是向后兼容的,但为什么原始版本的库无法直接使用jdk 1.8?
因为ASM是一个在Java字节码上运行的工具。 字节码格式改为引入新function。 因此,您必须升级该工具以支持新的字节码。
请注意,使用较旧版本的JDK编译的软件并不总是适用于较新版本的Java。 例如,在早期版本的JDK中, enum
不是关键字。
ASM是一个非常低级的库。
它直接处理Java字节码(而“普通”应用程序只是让JVM加载它的类)。 字节码格式会不时更改,较旧的JVM不能使用较新的版本。
向后兼容性不包括与JDK或类格式内部的混淆。
这实际上是一个边缘情况,ASM几乎是唯一的“流行”示例。
更重要的是(也更常见)系统库代码中的轻微行为变化。 因此,您的应用程序在技术上仍会运行,但以不同的方式执行。 大多数情况下,您需要这样,因为它意味着改进(例如更好的性能),但有时它可能会导致您的错误。
例如:
- 切换到64位JVM可能需要更多内存
- 垃圾收集中的更改可能会导致意外暂停
- 将XML解析器包含到JDK中需要更改Web应用程序打包或配置
- String#substring的内存和运行时特性在“次要”JDK修订版中完全改变
- 使用自定义(错误实现的)比较器对集合进行排序会突然抛出之前未抛出的exception
- 调用线程#stop(Throwable)(这从来就不是一个好主意并且已被弃用了很长时间)会抛出UnsupportedOperationException,因为Java 8
- 更新了Unicode支持,更改了某些字符串的排序和大小写行为
- generics编译的变化
- 由于新的默认方法,无法扩展BitSet并实现Set
- 舍入行为的变化
- API和BPI中还有许多其他变化
但总体来说,遗留的应用程序兼容性故事对Java来说非常好。 他们必须牢记所有企业客户。