在JVM版本6上执行编译为字节代码的类并在较低版本的JVM(例如1.4)上执行相同的操作会产生什么影响?
答案 0 :(得分:4)
不确定你真正在问什么,但是如果你编译一个针对Java 6的Java源文件,它将不会在较旧的JVM上执行(例如,1.4)。
: ~/tmp > javac -version
javac 1.6.0_22
: ~/tmp > javac Test.java
: ~/tmp > java Test
Hello World
: ~/tmp > module add jdk/1.4.2 # switching to Java 1.4.2
: ~/tmp > java Test
Exception in thread "main" java.lang.UnsupportedClassVersionError:
Test (Unsupported major.minor version 50.0)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:539)
at java.security.SecureClassLoader.defineClass(ClassLoader.java:123)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)
: ~/tmp >
正如@ The-MeLLeR指出的那样,您仍然可以使用1.6编译器通过-target
选项编译为1.4兼容代码。但是请记住,只有在您不使用任何1.5 / 1.6特定功能或API类时,这才有效。
如果您尝试编译for-each循环,使用-target 1.4
,您将获得类似于以下消息的内容:
Test.java:3: ';' expected
for (int i : new int[] { 1, 2, 3 })
^
答案 1 :(得分:1)
除非使用-target命令行选项进行编译,否则它不会在较旧的JVM上运行。
使用-target选项编译时,编译的类应该在较旧的(但不是旧的,然后是[target])jvm上运行100%。
答案 2 :(得分:1)
如果尝试使用为新JVM编译的类而不是当前JVM支持的类,则JVM在尝试加载类时将抛出UnsupportedClassVersionError
。较新的类格式可能具有旧JVM不支持的功能,因此这是必要的。
可以使用javac的-target
选项使用较旧的类格式生成较新的JDK生成类。但是你仍然需要注意不要使用只存在于新JRE上的类或方法 - 否则JVM会在类加载时抛出一些错误。使用与目标版本相同的JDK版本是最安全的选择。
P.S。如果您使用太新的方法/类,IntelliJ IDEA会进行检查以发出警告。还有一个名为Retroweaver的工具可以在Java 1.4上运行Java 5代码。