Java版本之间是否存在后向不兼容的具体示例?

kno*_*orv 48 java jvm bytecode backwards-compatibility

Java版本之间是否存在不兼容性,其中针对Java版本X的Java源代码/ Java类文件将无法在版本Y(其中Y> X)下编译/运行?

"Java发布"我指的是以下版本:

  • JDK 1.0(1996年1月)
  • JDK 1.1(1997年2月)
  • J2SE 1.2(1998年12月)
  • J2SE 1.0(2000年5月)
  • J2SE 1.4(2002年2月)
  • J2SE 5.0(2004年9月)
  • Java SE 6(2006年12月)

家庭规则:

  • 请尽可能包含参考和代码示例.
  • 请尽量在答案中具体/具体.
  • 被标记为@Deprecated的类不计为向后不兼容.

McD*_*ell 24

各种版本的兼容性说明:

我记得的第一个主要打嗝是assert在Java 1.4中的引入.它影响了很多JUnit代码.

  • 引入新的保留关键字应该受到严厉惩罚!他们用枚举再次做到了. (7认同)
  • 然而他们从未删除过goto作为保留字! (3认同)
  • 有趣的是,官方笔记中没有关于JDBC包不兼容性的评论.还是我想念它? (2认同)

Sea*_*lly 19

首先,Sun实际上认为你提到的所有版本(当然不是1.0)都是次要版本,而不是主要版本.

我不知道那时候二进制不兼容的任何例子.但是,有一些源不兼容的例子:

  • 在Java 5中,"enum"成为一个保留字; 它不是之前.因此,有一些源文件使用枚举作为标识符,将在java 1.4中编译,不能在java 5.0中编译.但是,您可以使用-source 1.4进行编译以解决此问题.

  • 向接口添加方法也会破坏源兼容性.如果您实现了一个接口,然后尝试使用向接口添加新方法的JDK编译该实现,则源文件将不再成功编译,因为它不会实现所有接口的成员.java.sql.Statement和其他jdbc接口经常发生这种情况.除非您实际调用其中一个不存在的方法,否则这些"无效"实现的编译形式仍然有效; 如果你这样做,将抛出一个MissingMethodException.

这些是我可以回想起的一些例子,可能还有其他的例子.

  • 最糟糕的部分是JDBC接口中添加的一些方法依赖于早期版本中不存在的新类型.这意味着不可能实现可以在JDK的多个版本中编译的实现. (3认同)
  • 我上周在工作中遇到了这个问题.我们最终编写了一个动态代理来获得一个可以在Java 5和Java 6中编译的实现. (3认同)

tan*_*ens 15

接口java.sql.Connection从Java 1.5扩展到Java 1.6,使得实现此接口的所有类的编译失败.


Yis*_*hai 11

Swing的每一个版本都为我们打破了一些东西,从1.3到1.6.

已经提到了JDBC问题,但现有代码有效.

从1.5到1.6,Socket的行为发生了变化,打破了思科客户端.

当然会引入新的保留关键字.

我认为在Sun方面真正不可原谅的一个重要因素是System.getenv().它在1.0中运行,然后被弃用并更改为在所有平台上抛出错误,这是因为Mac没有系统环境变量.然后Mac得到了系统环境变量,因此在1.5中它没有被提及并且有效.这样做没有合理的理由.在Mac上返回一个空集(如果你想关心那个级别的跨平台一致性,Swing有更大的跨平台问题),甚至在所有平台上.

我从不同意他们关闭这个功能,但改变它以引发错误只是一个纯粹的改变,如果他们要做的话,他们应该完全删除该方法.

但是,实际上从1.0到1.1,他们不太关心向后兼容性.例如,他们将"private protected"作为修饰符.

所以结果就是每个版本都有足够的变化需要仔细评估,这就是为什么你仍然会在SO上看到很多1.4问题.


Dan*_*yer 10

我能想到的主要是引入新的保留字:

Java 1.3: strictfp
Java 1.4: assert
Java 5.0: enum
Run Code Online (Sandbox Code Playgroud)

以前使用这些值作为标识符的任何代码都不会在更高版本下编译.

我记得在我工作的项目中导致问题的另一个问题是JInternalFrames的默认可见性在1.2和1.3之间发生了变化.它们默认是可见的,但是当我们升级到1.3时,它们似乎都消失了.


rsp*_*rsp 8

在1.3和1.4之间,Long.parseLong(String)的解释以不同方式处理空字符串.1.3返回一个0值,而1.4抛出一个NumberFormatException.

不需要重新编译,但如果依赖于1.3行为,则工作代码停止工作.


Tho*_*ung 7

内存模型 的语义从1.4变为1.5.它被改为允许除了其他东西再次双重检查锁定.(我认为易失性语义是固定的.)它被打破了.

  • @Jason:你知道,有一个编辑按钮. (4认同)