Java 二进制兼容性发生了什么变化?

2022-09-02 14:08:01

我偶然发现了一套1997年3月的旧课程。那是在我试图学习Java的时候,它是JDK 1.0.2。

有趣的是,从那时起,我的源文件和类文件都完好无损。源代码仍然按预期编译和执行,这真的很酷。但是Java不是也应该保持二进制兼容性吗?好吧,在此过程中的某个地方,格式不再有效。Java 8 VM 将报告;

Exception in thread "main" java.lang.ClassFormatError: Invalid start_pc 65535 in LocalVariableTable in class file bali/core/Application
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    :
    [snip many ClassLoader calls]
    :
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

违规类是我从命令行调用的类的超类。

还有一个细节,在那些日子里,微软仍然处于Java阵营,我记得他们的javac更符合写得不好的语法。Sun 编译器很乐意接受“公共同步类 Abc”和许多其他无效语句。因此,这些类文件很有可能是由 MS 编译器生成的,然后在 Sun JVM 上运行。

无论如何,我的问题是;周围有没有人了解早期版本的Java中的兼容性承诺?这是一件大事,还是故意牺牲的?还是很久以后才决定,比如Java 1.4或Java 5,简单地放弃对JDK 1.0的支持?


答案 1

正如你所提到的,当编译器从Microsoft编译器切换到Sun编译器时,可能会引入这个问题。Sun表示,微软编译器生成的类文件不符合Java规范,因此无效。

您可以在此处找到更多详细信息:

此错误是由旧的 JDK 1.0.2 或 1.1 编译器生成的字节码引起的。过去,这些编译器中的许多编译器生成的字节码不符合 Java VM 规范。由于最近的 J2SE 发行版中的验证程序对错误的类格式要严格得多,因此在加载这些错误的类文件时,VM 会抛出 ClassFormatError。

关于一般问题,Java仍然坚定地致力于向后兼容性,从来没有重大突破。在边缘问题上,从发布到发布通常会有一些小的中断。我知道没有主表,但这里有个别版本的表:

  • Java 8(与 Java 7 完全二进制兼容)
  • Java 7(大部分与Java 6兼容的二进制文件)
  • Java 6(大部分与Java 5兼容二进制文件,加上一些混淆器在规范之外生成类文件,因此这些类文件可能无法运行)
  • Java 5(大部分与Java 1.4.2兼容的二进制文件,以及关于混淆器的相同注释)
  • Java 1.0 - 1.4.2(主要是与以前的版本兼容的二进制文件,一些评论认为向前兼容性甚至可能有效,但未经测试)

答案 2

推荐