捕获具有交集类型参数的可序列化lambda时的ClassCastException

时间:2016-12-21 01:32:17

标签: lambda java-8 intersection classcastexception type-variables

我尝试使用类型变量类型交集来捕获lambda时复制了一个异常;具体来说,为了复制,我试图抓住一个lambda为F <A, F extends Consumer<A> & Serializable>

public class Consumers {

    public static <A, F extends Consumer<A> & Serializable>
    Consumer<A> serializable(F action) {
        return action;
    }

    public static <A> Consumer<A> vary(Consumer<? super A> action) {...}

    private static final Consumer<Object> DOES_NOTHING =
            serializable(a -> {});

    public static <A> Consumer<A> doesNothing() {
        return vary(DOES_NOTHING);
    }

    ...
}

Consumer<String> action = Consumers.doesNothing(); // throws class cast exception

以下是抛出异常的示例:

 java.lang.ClassCastException: [insert lambda name] cannot be cast to java.util.function.Consumer

我可以将Consumers.serializable用于本地变量或实例变量;尝试初始化静态变量时抛出此异常。

这是正确的行为吗?我正在使用最新的Eclipse Oxygen,JDK u112。

1 个答案:

答案 0 :(得分:0)

不应该允许这样做:javac抱怨:

Consumers.java:??: error: incompatible types: cannot infer type-variable(s) A,F
            serializable(a -> {});
                        ^
    (argument mismatch; Consumer<Object> cannot be converted to INT#1)
  where A,F are type-variables:
    A extends Object declared in method <A,F>serializable(F)
    F extends Consumer<A>,Serializable declared in method <A,F>serializable(F)
  where INT#1 is an intersection type:
    INT#1 extends Object,Serializable,Consumer<Object>

它实际上是一个Eclipse编译器bug,已在4.6 M6(Neon)中修复,并且已在此other question中注意到。