为什么Eclipse让我将一些Java 7语言特性编译成Java 6类文件?
我发现在Eclipse中(使用Eclipse编译器),我可以使用一些Java7语言特性,但仍然可以创建Java6类文件。在下图中,您可以看到两个Java 7语言功能已成功编译为Java 6类文件。然而,其他Java7特性(那些被注释掉的特性)不会编译 我的假设是Eclipse正在确定哪些Java 7语言特性与Java 6 JVM兼容,哪些不兼容。例如,泛型类型JComboBox只是一个编译(而不是运行时)特性,因此我可以想象它是如何兼容的。虽然我认为开关字符串特性可能会在字节码上产生差异,并依赖于新的JVM特性,但我可能错了 我的问题是:为什么Eclipse让我将一些Java 7语言特性编译成Java 6类文件?,java,eclipse,ecj,Java,Eclipse,Ecj,我发现在Eclipse中(使用Eclipse编译器),我可以使用一些Java7语言特性,但仍然可以创建Java6类文件。在下图中,您可以看到两个Java 7语言功能已成功编译为Java 6类文件。然而,其他Java7特性(那些被注释掉的特性)不会编译 我的假设是Eclipse正在确定哪些Java 7语言特性与Java 6 JVM兼容,哪些不兼容。例如,泛型类型JComboBox只是一个编译(而不是运行时)特性,因此我可以想象它是如何兼容的。虽然我认为开关字符串特性可能会在字节码上产生差异,并依赖
- Eclipse真的足够聪明,可以知道哪种Java 7语言吗 特性能够被编译成Java6类文件,并且 不是吗
- 下面的示例显然与1.6源代码不兼容,那么为什么将“源代码兼容性”设置为1.6不会导致错误
- 这个“技巧”似乎让我至少可以使用一些Java7语言特性,并且仍然可以创建Java6类文件。将javac与源代码1.7和目标代码1.6一起使用会失败,那么为什么会这样呢?Ecilpse编译器有javac没有的特性吗
我想你是对的,当设置为Java 6时,为什么ECJ会编译一些东西而不是其他东西。泛型只是编译成与强制转换相同的东西,所以如果目标设置为Java6,这可能就是它工作的原因
有关javac和ECJ之间的其他差异,请参阅。我认为有两件事正在发生:
JComboBox
)是有效的,因为链接的是Java1.7rt.jar
,而不是Java1.6rt.jar
(我有一个使用JavaSE-1.6设置的项目,在这种情况下,第一行即使使用第一组设置也不会编译)。但这是一个类库问题,而不是语言版本问题。(如果您使用比运行时更新的rt.jar
编译Java应用程序,即使使用javac
,也会遇到很多问题)因此,简而言之,您在(可能)不寻常的Eclipse配置中至少发现了一个bug。小心,不要依赖它。这可能是因为在项目的构建路径上配置的JRE系统库与您选择的法规遵从性级别不匹配。通常,您几乎总是希望在项目的编译器设置中选择“从执行环境使用法规遵从性”选项。检查项目的构建路径,看看是否已将JRE系统库指定为执行环境。我不知道Eclipse为什么允许这样做,或者这是否只是一个bug。1.7
javac
将告诉您
error: strings in switch are not supported in -source 1.6
我也不知道为什么JComboBox
能工作
System.out.println(new JComboBox<String>() {}.getClass().getGenericSuperclass());
> javax.swing.JComboBox<java.lang.String>
本质上成为
int java6(String string) {
switch (string.hashCode()) {
case 2112:
if (string.equals("BB"))
return 12;
break;
case 2166379:
if (string.equals("FRED"))
return 13;
break;
}
return 0;
}
这是基于String#hashCode()
的结果是指定的,不能更改。编译器只需为您节省一些时间,就可以更快地编写其他合法代码
这同样适用于菱形运算符:例如,new ArrayList()
可以由编译器简单地解析
android工具允许同样的semi 7兼容性,允许您使用它。但是,不同之处在于它们使用的.class文件是针对Java7的。Android需要将.class文件转换为它的内部格式,因此它们的.class到.dex编译器可以使用任何输入来生成Android运行时可以理解的指令
例如,try with resource将不起作用,因为它需要Java 6中不存在的AutoCloseable
接口
像Lambda表达式这样的特殊功能也需要新类型的字节码
int java6(String string) {
switch (string.hashCode()) {
case 2112:
if (string.equals("BB"))
return 12;
break;
case 2166379:
if (string.equals("FRED"))
return 13;
break;
}
return 0;
}