Eclipse:类型推断期间的“未知错误”

时间:2017-07-03 08:37:33

标签: java eclipse lambda java-8

使用某些现有代码时,我在运行时使用 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的第一个参数会导致类型推断中断,因为将其替换为相同类型的另一个实例(但显式声明而不是推断)会消除错误。

知道类中错误的确切来源允许我们重写代码(将传递给外部的lambda表达式提取为自己的方法)。但是,我仍然有兴趣解释为什么这样的构造可能会破坏两个新的eclipse编译器。

1 个答案:

答案 0 :(得分:3)

对我而言 public string GetCustomUI(string ribbonID) { string ribbonXML = String.Empty; if (ribbonID == "Microsoft.Outlook.Mail.Compose") { ribbonXML = GetResourceText("Trin_RibbonOutlookBasic.Ribbon1.xml"); } return ribbonXML; } ,只需声明减少的参数就可以了:

Oxygen

了解确切的问题以及为什么eclipse编译器无法推断出类型对我来说太过分了;无论哪种方式都应报告(日食团队可能已经知道)。

我还可以确认它与(MyMap<MyKey, MyValue> map, MyValue value) -> .... jdk-8-131

一起编译正常