【发布时间】:2017-08-17 02:53:41
【问题描述】:
以下代码在 Eclipse 版本中编译:Mars.2 Release (4.5.2) Build id: 20160218-0600 on Windows 10 Version 10.0.14393。它不能在一系列 oracle javac 编译器上编译。还有其他关于使用 Eclipse JDT 编译器而不是 javac 编译的代码片段的问题。我找不到与此示例类似的内容。这是一段玩具代码,它的唯一目的是展示这种好奇心。
eclipse编译器编译这个是否正确?
注意:如果 eclipse 编译器生成的 .class 被反编译,它会生成可以用 javac 编译的源代码。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Puzzle {
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
List<List> outer = Arrays.asList(Arrays.asList(new Object(), new Object()),
Arrays.asList(),
Arrays.asList(new Object(), new Object()));
Stream<Boolean> bs1 = outer.stream().flatMap(inner -> inner.stream()).map(obj -> obj.hashCode() % 2 == 0);
boolean b0 = bs1.filter(b -> !b).findAny().isPresent();
boolean b2 = outer.stream().flatMap(inner->inner.stream())
.map(obj -> obj.hashCode() % 2 == 0)
.filter(b -> !b).findAny().isPresent();
System.out.printf("%s %s %s", outer, b0, b2);
}
}
这是编译器错误,在几个版本的编译器中:
C:\Users\tofti>C:\jdk1.8.0_121\bin\javac -version & C:\jdk1.8.0_121\bin\javac Puzzle.java
javac 1.8.0_121
Puzzle.java:23: error: bad operand type Object for unary operator '!'
.filter(b -> !b).findAny().isPresent();
^
1 error
C:\Users\tofti>C:\jdk1.8.0_112\bin\javac -version & C:\jdk1.8.0_112\bin\javac Puzzle.java
javac 1.8.0_112
Puzzle.java:23: error: bad operand type Object for unary operator '!'
.filter(b -> !b).findAny().isPresent();
^
1 error
C:\Users\tofti>C:\jdk1.8.0_141\bin\javac -version & C:\jdk1.8.0_141\bin\javac Puzzle.java
javac 1.8.0_141
Puzzle.java:23: error: bad operand type Object for unary operator '!'
.filter(b -> !b).findAny().isPresent();
^
1 error
下面是在 Eclipse 中编译和执行的代码: Code compiling and running in eclipse
【问题讨论】:
-
看起来像一个 Eclipse 错误。在 4.6.3 build 20170314-1500 中无法为我编译。
-
如果两个编译器都拒绝它,它可能不应该编译。至于为什么,控制类型推断的规则非常复杂。随时在这里阅读:docs.oracle.com/javase/specs/jls/se8/html/jls-18.html
-
是的,javac只有一个错误。从类型的角度来看,这两段代码有何不同?一个较长的陈述和两个较短的陈述?我包括了这两个变体以突出好奇心。
-
我对问题进行了修改,以明确存在一个错误,并且它出现在测试的编译器的多个版本中。
-
你也可以这样做 (b->!((boolean)b)),但我认为这应该直接编译,没有额外的提示
标签: java eclipse generics java-stream