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

Java版本之间是否存在向后不兼容的具体示例?,java,jvm,bytecode,backwards-compatibility,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.3(2000年5月) J2SE 1.4(2002年2月) J2SE 5.0(2004年9月) 爪哇SE 6(2006年12月) 众议院规则: 请尽可能提供参考资料和代码示例 请尽量在回答中非常具体/具体 标记为@

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.3(2000年5月)
  • J2SE 1.4(2002年2月)
  • J2SE 5.0(2004年9月)
  • 爪哇SE 6(2006年12月)
众议院规则:

  • 请尽可能提供参考资料和代码示例
  • 请尽量在回答中非常具体/具体
  • 标记为@Deprecated的类不算向后不兼容

    • 的语义。它被更改为允许再次进行双重检查锁定。(我认为volatile语义是固定的。)它被破坏了。

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

      首先,Sun实际上认为您提到的所有版本(当然除了1.0)都是次要版本,不是大的

      我不知道当时有任何二进制不兼容的例子。但是,也有一些源不兼容的例子:

      • 在Java5中,“enum”变成了一个保留字;以前没有。因此,有一些使用enum作为标识符的源文件将在Java1.4中编译,而在Java5.0中则不会编译。但是,您可以使用-source 1.4进行编译来解决这个问题

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


      这些都是我能回忆起的几个例子,可能还有其他的。

      正如肖恩·赖利所说,一种新方法可以破解你的代码。除了必须实现新方法的简单情况(这将产生编译器警告)之外,还有一种最坏的情况:接口中的新方法具有与类中已有方法相同的签名。编译器发出的唯一提示是警告缺少
      @Override
      注释(Java 5对于类,Java 6中的接口支持注释,但可选)。

      各种版本的兼容性说明:


      我记得的第一个主要问题是在Java1.4中引入了
      assert

      以下内容将在Java 1.4下编译,但不在Java 1.5或更高版本下编译

      (Java 5引入了“enum”作为关键字。注意:如果提供“-source 1.4”选项,它将在Java 5中编译。)


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


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

      我没有尝试过,但理论上这在Java 1.1中可以工作,在Java 1.2中则会中断。(更多)


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

      Java 1.3: strictfp
      Java 1.4: assert
      Java 5.0: enum
      
      以前使用这些值作为标识符的任何代码都不会在更高版本下编译


      我记得在我所从事的项目中造成问题的另一个问题是,存在。默认情况下它们是可见的,但当我们升级到1.3时,它们似乎都消失了。

      java.sql破坏兼容性的另一个例子:

      在1.5中,在java.sql.Timestamp中添加了compareTo(日期)方法。如果提供的日期不是java.sql.Timestamp的实例,此方法将抛出ClassCastException。当然,java.sql.Timestamp扩展了Date,Date已经有了一个compareTo(日期)方法,可以处理所有日期,因此这意味着将时间戳与(非时间戳)日期进行比较的代码将在运行时在1.5中中断


      有趣的是,1.6似乎已经解决了这个问题。虽然java.sql.Timestamp.compareTo(Date)的文档仍然说“如果参数不是
      Timestamp
      对象,则此方法抛出
      ClassCastException
      对象”,但实际的实现却相反。我猜这是一个文档错误。

      显然,的命名约定是

      • JDK 1.0(1996年1月23日)
      • JDK 1.1(1997年2月19日)
      • J2SE 1.2(1998年12月8日)
      • J2SE 1.3(2000年5月8日)
      • J2SE 1.4(2002年2月6日)
      • J2SE 5.0(2004年9月30日)
      • 爪哇SE 6(2006年12月11日)
      • JavaSE6更新10、更新12、更新14、更新16
      • JavaSE7???JDK7

      (.)从1.3到1.6,Swing的每一次发布都会给我们带来一些麻烦

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

      从1.5到1.6,套接字的行为发生了变化,导致Cisco客户端崩溃

      当然引入了新的保留关键字

      我认为Sun方面真正不可原谅的一个大问题是System.getenv()。它在1.0中工作,然后被弃用并更改为在所有平台上抛出一个错误,理由相当可疑,即Mac没有系统环境变量。然后Mac获得了系统环境
      public class Test {
          float strictfp = 3.1415f;
      }
      
      Java 1.3: strictfp
      Java 1.4: assert
      Java 5.0: enum