I am having a stump of a time understanding the condundrum below. Here is a code snippet that compiles, yet throws the exception
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");
}
}
What stumps me is that the Java compiler can generate a proper IntegerConsumer-compatible object out of the lambda on line 20, yet the previously constructed non-generic lambda constructed as the singleton on line 8 can not be used. Is that because the lambda on line 20 has a reifiable subtype of the Consumer that fits the type of the IntegerConsumer reference immediately, whereas the lambda that is cast on line 10 can not be cast at runtime to a real subtype of Consumer ? But then shouldn't the generic bounded type declaration on line 8 take care of that? Any help is really appreciated !