在处理一些现有代码时,我在使用 Eclipse Neon.3 运行代码时遇到了运行时问题。不幸的是,我无法在最小的工作示例中重现异常,但类加载器生成了以下输出:
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
...
Reason:
Type 'java/lang/Object' (current frame, stack[8]) is not assignable to 'MyMap'
Current Frame:
...
Bytecode:
...
Stackmap Table:
...
它可以在命令行和旧的 eclipse 版本中运行,所以当时它并不重要。上周,Eclipse Oxygen.1 发布,我们开始使用它。现在,相同的代码会产生一个编译时异常:
Problem detected during type inference: Unknown error at invocation of reduce(Main.MyMap<MyKey,MyValue>, BiFunction<Main.MyMap<MyKey,MyValue>,? super MyValue,Main.MyMap<MyKey,MyValue>>, BinaryOperator<Main.MyMap<MyKey,MyValue>>)
我已经设法组合了一个在 Eclipse 中产生此错误但在命令行上工作的最小工作示例:
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class Main<MyKey, MyValue> {
static class MyMap<K, V> extends HashMap<K, V> {
public MyMap<K, V> putAllReturning(MyMap<K, V> c) { putAll(c); return this; }
public MyMap<K, V> putReturning(K key, V value) { put(key, value); return this; }
}
public Main() {
Set<MyValue> values = new HashSet<>(); // actually something better
final MyMap<MyKey, MyValue> myMap =
values.stream()
.reduce(
new MyMap<MyKey, MyValue>(),
(map, value) -> {
Set<MyKey> keys = new HashSet<>(); // actually something better
return keys.stream()
.reduce(
map, // this would work syntactically: new MyMap<MyKey, MyValue>(),
(map2, key) -> map2.putReturning(key, value),
MyMap::putAllReturning);
},
MyMap::putAllReturning
);
}
}
似乎内部 reduce 的第一个参数导致类型推断中断,因为用另一个相同类型的实例替换它(但显式声明而不是推断)消除了错误。
了解类中错误的确切来源后,我们可以重写代码(将传递给外部 reduce 的 lambda 表达式提取到它自己的方法中)。但是,我仍然对解释为什么这样的构造可能会破坏两个较新的 eclipse 编译器感兴趣。
最佳答案
对我来说,在 Oxygen
上,它通过简单地声明 reduce 的参数来工作:
(MyMap<MyKey, MyValue> map, MyValue value) -> ....
了解确切 问题以及为什么 eclipse 编译器无法推断类型对我来说太多了;无论哪种方式,都应该报告(eclipse 团队可能已经知道)。
我还可以确认它使用 jdk-8-131
和 jdk-9-175
编译正常
关于java - Eclipse:类型推断期间为 "Unknown error",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44881076/