Java是向后兼容的,但是当我们将jdk从1.6升级到1.8时,为什么我们需要升级许多库?

最近,我在一个Java项目中将Jdk版本从1.6升级到1.8 。 但是有一些编译或运行时错误,所以我必须升级一些库:

  • gradle: 1.91.10
  • 弹簧: 3.x4.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来说非常好。 他们必须牢记所有企业客户。