【发布时间】:2020-11-10 03:34:24
【问题描述】:
我很难理解下面的难题。这是一个可以编译但抛出异常的代码 sn-p
Exception in thread "main" java.lang.ClassCastException:
TestGenericSingleton$$Lambda$1/303563356 cannot be cast to
TestGenericSingleton$IntegerConsumer
at TestGenericSingleton.main(TestGenericSingleton.java:23)
import java.util.function.Consumer;
public class TestGenericSingleton
{
static final Consumer<Object> NOOP_SINGLETON = t -> {System.out.println("NOOP Consumer accepting " + t);};
@SuppressWarnings("unchecked")
static <R extends Consumer<T>, T> R noopConsumer()
{
return (R)NOOP_SINGLETON;
}
static interface IntegerConsumer extends Consumer<Integer> {};
public static void main(String[] argv)
{
Consumer<Boolean> cb = noopConsumer();
cb.accept(true);
IntegerConsumer ic = t -> {System.out.println("NOOP Consumer2 accepting " + t);} ;
ic.accept(3);
ic = noopConsumer();
ic.accept(3);
System.out.println("Done");
}
}
让我难过的是,Java 编译器可以从第 20 行的 lambda 生成一个适当的 IntegerConsumer 兼容对象,但不能使用之前在第 8 行构造为单例的非泛型 lambda。是不是因为第 20 行的 lambda 具有 Consumer 的可具体化子类型,它立即适合 IntegerConsumer 引用的类型,而第 10 行强制转换的 lambda 不能在运行时强制转换为真正的 Consumer 子类型?但是第 8 行的通用有界类型声明不应该处理这个问题吗?非常感谢任何帮助!
【问题讨论】:
-
因为你有一个演员,编译器不能完成它的工作。它知道第 20 行生成的内部类需要实现 IntegerConsumer,所以它实现了。它无法在第 5 行生成内部类。但也许我误解了你的问题?
-
我认为原因很明显。 Comsumer