Came accross this today and spent ages trying to reproduce/figure out what was happening. Can somebody explain why this happens or is this a bug with type erasure/default methods/lambda's/polymorphism? Uncommenting the default method makes it run fine, but I would have expected this to work as is
Output:
Works fine with an object
Calling consume
Hello
Calling accept with context
Hello
Calling accept via consumer...
Exception in thread "main" java.lang.AbstractMethodError: Method test/LambdaTest$$Lambda$1.accept(Ljava/lang/Object;)V is abstract
at test.LambdaTest$$Lambda$1/834600351.accept(Unknown Source)
at test.LambdaTest.main(LambdaTest.java:24)
Code
package test;
import java.util.function.Consumer;
public class LambdaTest {
public static void main(String[] args) {
Consumer<Context> contextIgnoringObject = new ContextUnawareObject();
contextIgnoringObject.accept(new Context());
ContextIgnorer contextIgnoringLambda = () -> {
System.err.println("Hello");
};
System.err.println("Calling consume");
contextIgnoringLambda.consume();
System.err.println("Calling accept with context");
contextIgnoringLambda.accept(new Context());
Consumer<Context> consumer = contextIgnoringLambda;
System.err.println("Calling accept via consumer...");
consumer.accept(new Context());
}
@FunctionalInterface
public interface ContextIgnorer extends Consumer<Context> {
// default void accept(Object object) {
// System.err.println("Manual bridge method");
// accept((Context)object);
// }
@Override
default void accept(Context context) {
consume();
}
void consume();
}
public static class ContextUnawareObject implements ContextIgnorer {
@Override
public void consume() {
System.err.println("Works fine with an object");
}
}
public static class Context {
}
}
The problem appears with older ECJ compiler (3.10.0):
$ java -jar org.eclipse.jdt.core-3.10.0.v20140604-1726.jar -source 1.8 LambdaTest.java
$ java LambdaTest
Works fine with an object
Calling consume
Hello
Calling accept with context
Hello
Calling accept via consumer...
Exception in thread "main" java.lang.AbstractMethodError: Method LambdaTest$$Lambda$1.accept(Ljava/lang/Object;)V is abstract
at LambdaTest$$Lambda$1/424058530.accept(Unknown Source)
at LambdaTest.main(LambdaTest.java:24)
Using org.eclipse.jdt.core_3.10.0.v20140902-0626.jar or newer solves the problem. The Oracle javac compiler has no such problem. Thus the solution would be to update your ECJ compiler or move to the javac.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With