如果我使用最新的JDK编译Java文件,旧版本的JVM能否运行.class文件?

40

字节码是否取决于创建它所使用的Java版本?

7个回答

42
如果我使用最新的JDK编译一个Java文件,那么旧版本的JVM能否运行“.class”文件,这取决于以下三个因素:1)实际使用的Java版本,例如,1.4.0的JVM可以运行由1.4.2编译器编译的代码,但1.3.x的JVM不能。2)使用的编译标志。有一个“-target”编译器标志,它告诉它生成可在较旧(目标)JVM上运行的代码。“-source”编译器标志告诉它仅接受较旧JVM的语言特性。(这种方法不总是有效,具体取决于代码使用的Java语言特性。但如果代码编译了,则应该有效。)3)类文件使用的库类。如果它使用的是旧的类库中不存在的库类,则它将无法运行...除非您可以包含一个回溯类的JAR。您可以通过使用“-bootclasspath”选项来避免此问题,以针对旧版本Java的API编译代码。 字节码是否取决于创建它的Java版本?是的,除了上述几点。

2- 进行后移可能也会有问题。例如:1)依赖本地代码支持的事物很可能需要您实现该本地代码支持。2)当您在旧JVM上运行代码时,您很可能需要将任何后移的JAR文件放到bootclasspath中。


10

字节码是否取决于创建它所使用的Java版本?

通常是的。但是,通过使用 -source、-target和-bootclasspath选项,可以使用 1.7+ 编译器创建与 Java 1.1 兼容的二进制文件。


请注意,JDK 1.8表示编译目标为1.5已被弃用,并且JDK 1.9将完全删除对目标1.5的支持:http://openjdk.java.net/jeps/182 ...但是,在JDK 1.9上,编译旧版本更容易,因为不需要bootclasspath:http://openjdk.java.net/jeps/247 - juhist

4

首先,所有的Java文件都有一个版本字节在类头中。较旧的JVM无法加载具有较新版本的类,无论它们具有什么功能。


3

JVM字节码在主要JVM版本之间具有向前兼容性,但不具备向后兼容性。然而,要获取最佳信息,您需要阅读JVM发布说明,因为它们通常会指出字节码的向后兼容性。

编辑澄清,因为这引起了评论中的讨论

JVM字节码具有向前兼容性,这意味着从一个JVM中提取的字节码可与较新版本的JVM一起运行。例如,您可以将1.4 JVM中的字节码运行在Java 5或Java 6 JVM中(除了Andrew所指出的任何回归问题)。

JVM字节码在不同的JVM之间不具备向后兼容性,这意味着在以前的JVM版本中不能保证来自某个JVM的字节码能够正常工作,就像尝试在1.4.2 JVM中运行为Java 6编译的代码一样。


1
@birryree:新版本向后兼容,旧版本不向前兼容。这样说更有意义,你觉得呢? - Adeel Ansari
1
@Adeel:我认为你的评论才是无意义的。在Java 1.1中创建的小程序应该可以在Java 1.6中正常运行,除非存在回归错误。 - Andrew Thompson
@Andrew:我说的话和你完全一样。我有没有以某种不同的方式表达它?新版本向后兼容,这意味着1.1小程序应该可以在1.6中正常运行。 - Adeel Ansari
@Andrew:你让我开始怀疑自己的话了。是的,我们应该坚持你的建议。问题在于,我不是以英语为母语的人,所以你很可能是对的。 :) - Adeel Ansari
@Muhammad - 我在谈论编译后的字节码兼容性。对于源代码,源代码也是向前兼容的(例如,在Java 5和Java 6中编译Java 1.4.2的代码),但如果您使用后续版本添加的任何功能(例如使用泛型并尝试在Java 1.4.2中编译),反之则不一定成立。 - wkl
显示剩余2条评论

1

字节码是否取决于创建它的Java版本?

是的。

如果我在最新的JDK中编译了一个Java文件,旧的JVM能否运行.class文件?

不行。但相反的情况可能会起作用。您可能会喜欢查看这个有趣的线程,它讨论了Java的后移植。


1
不,除非你将旧的JVM指定为目标。
例如,使用Java 6,您可以编译并在Java 1.4中运行:
javac -target 1.4 SomeClass.java

显然源代码应该是1.4兼容的。


0

如果您不使用高版本JVM中可用的功能,则可以编译与旧版本JVM兼容的类。

javac -target 1.5 MyJava.java

javac -target 1.4 MyJava.java


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接