在Java 1.8上,您不必将字段定义为final
,以便从匿名类中获取它。
例如,旧版本:
public void foo(final int bar) {
new Runnable() {
public void run() {
System.out.println(bar);
}
};
}
但是,现在,在Java 1.8上,bar
不需要是最终的:
public void foo(int bar) {
new Runnable() {
public void run() {
System.out.println(bar);
}
};
}
所以,如果我编译我的项目,并且我在Java 1.8上使用的唯一资源就是这个(我没有使用任何lambdas,新类等),我的代码是否可以执行具有较旧Java版本的计算机?如果没有,为什么?
答案 0 :(得分:6)
使用-target 1.8
进行编译时,javac
将发出版本号为52.0
的类文件,以前的JVM不支持。因此,即使这是唯一的区别,它也会阻止您执行使用-target 1.8
编译的文件。
javac
不支持同时指定-source 1.8
和-target 1.7
。它将产生错误消息source release 1.8 requires target release 1.8
。
但实际上,如果使用有效的最终变量是您使用的唯一Java 8功能,除了版本号之外没有字节代码差异。如果您编译此类代码定位1.8
并修补类文件,将版本号减少到51.0
,它们将在Java 7上运行。这就像将索引7处的字节减少一样简单。
如果要创建Java 7兼容代码,那么在使用Java 8编译器时,要特别注意不要使用其他Java 8功能......
答案 1 :(得分:1)
我认为Java 8将类文件主要版本更改为与Java 7不同,因此较旧的JVM可能无法加载较新的类。
如果您使用-target 1.7编译,我不知道您是否可以有效使用最终
答案 2 :(得分:0)
如果编译没有-target 1.7 -source 1.7
的代码,它将被编译为更新的字节码版本,旧的JVM无法运行此类。
如果使用-target 1.7 -source 1.7
选项编译示例,则复杂化将失败
有消息
error: local variable bar is accessed from within inner class; needs to be declared final
System.out.println(bar);
^
所以,答案是否定的,你不能在旧的JVM上运行这样的代码