我发现在Eclipse中(使用Eclipse编译器)我可以使用一些Java 7语言功能,但仍然创建Java 6类文件.在下图中,您可以看到两个成功编译为Java 6类文件的Java 7语言功能.但是,那些注释掉的Java 7功能不能编译.
我的假设是Eclipse确定哪些Java 7语言功能与Java 6 JVM兼容,哪些不兼容.例如,泛型类型JComboBox只是一个编译(而不是运行时)功能,所以我可以想象它是如何兼容的.尽管我认为切换字符串功能可能会在字节代码中产生差异并依赖于新的JVM功能,但我可能错了......
我的问题:
Eclipse真的很聪明,知道哪些Java 7语言功能能够编译成Java 6类文件而哪些不是?
以下示例显然不是1.6源兼容,那么为什么将"Source compatibility"设置为1.6不会导致错误?
这个"技巧"似乎让我使用至少一些Java 7语言功能,仍然创建Java 6类文件.使用带有源1.7和目标1.6的javac会失败,那么为什么这样做呢?Ecilpse编译器是否具有javac不具备的功能?

为了便于比较,这是我按预期切换到Java 6编译器时的结果.

在运行时,在我的Java程序中,给定一个String,我想知道返回类型.例如:
1 + 1 回报 int1L + 1L 回报 long1L + 1 回报 long1 + 1.5 回报 double1 + 2 - 3 * 4 / 5 回报 int1 / 0 回报 int1 + Math.nextInt() 回报 int1.5 + Math.nextInt() 回报 doubleColor.RED 回报 java.awt.Colora是一个int:a + 1returninta是一个int:a + 1.5returndouble没有必要实际评估代码:我只需要返回类型.如何使用JDK运行时编译器,ECJ JDT或任何其他纯Java依赖项执行此操作?
详细代码:以下是此代码的简化伪代码单元测试:
public static void ExpressionTyper {
public String determineType(String expression, Map<String, …Run Code Online (Sandbox Code Playgroud) 似乎Java编译器(Jdk8)缺少类似'j = j ++;'的分配的警告。无效,但会为“ j = ++ j;”等赋值生成警告 确实有效。我已附上一个脚本进行演示。
请注意,您必须选择适当的标志来报告Java编译器Java编译器设置内的分配错误
public static void main(String[] args) {
int j = 0;
j = ++j; //Compiler warning: The assignment to variable j has no effect
System.out.println("j="+j); //Prints 1
int i = 0;
i = i++; //Compiler warning: 'None'
System.out.println("i="+i); //Prints 0
}
Run Code Online (Sandbox Code Playgroud)
这是Java编译器的错误吗?
在编译a时Client,它使用一些接口I(例如O)的实现,类文件I也必须存在于类路径中.奇怪的是,这只是一个例子javac,因为Eclipse编译器(ECJ)不需要I编译.
是什么让JDK 需要超类型进行编译,ECJ编译得很好?
它不是默认方法,如错误报告中所评论的那样,兼容性指南也同意:
在针对另一个实现在另一个类文件中定义的接口的类编译类时,这样的类文件(其中定义了接口)必须在编译期间由javac使用的类路径中可用.这是JDK 8的新要求 - 如果不这样做将导致编译错误.
更新:
I.doit()是default简单的抽象方法都没关系,行为是一样的I.doit()被覆盖,当然都很重要O; 如果没有覆盖,那么ECJ也会达到I定义doit()接口(api/a/I.java):
package a;
public interface I {
default void doit() {
System.out.println("In I");
}
}
Run Code Online (Sandbox Code Playgroud)
实施(impl/b/O.java):
package b;
public class O implements a.I {
public void doit() {
System.out.println("In O"); …Run Code Online (Sandbox Code Playgroud) 我在尝试打印JAVA8收藏家的结果时遇到Ambiguity错误.
我试图打印Product对象中的ID总和的结果,但得到以下错误:
"方法println(double)对于PrintStream类型是不明确的"
这是一小段代码,我收到编译错误:
编辑:添加代码段以获取更多详细信息:
package com.sample.reproduce.bugs;
public class Product {
private double id;
private String productName;
public double getId() {
return id;
}
public void setId(double id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我遇到编译错误的代码行:
System.out.println(productList.stream().collect(Collectors.summingDouble(x -> x.getId())));
Run Code Online (Sandbox Code Playgroud)
班级快照:
如果我将在一个单独的行中使用Collector(println方法之外),我不会收到任何错误.
如果我们在println()方法中使用它,为什么编译器无法检测到JAVA 8收集器的确切返回类型?
使用命令提示符添加另一种方法的细节:
我尝试使用相同JDK版本的命令提示符,并且程序已成功编译和执行.所以Holger的答案似乎是正确的.这似乎仅适用于Eclipse编译器: