ClassCastException when capturing a serializable lambda with intersection type parameters

228 views Asked by At

I've replicated an exception thrown when attempting to use type variable type intersection to capture lambdas; specifically, to replicate, I attempted to catch a lambda as F where <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

The following is an example of the exception thrown:

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

I'm able to use Consumers.serializable with local or instance variables; this exception is thrown when trying to initialize static variables.

Is this correct behavior? I'm using the latest Eclipse Oxygen, JDK u112.

1

There are 1 answers

1
HTNW On BEST ANSWER

This should not be allowed: javac complains:

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>

It is actually an Eclipse compiler bug, fixed in 4.6 M6 (Neon), and it has already been noticed in this other question.