Issue with lambdas
Issue #216
resolved
When using a lambda, like in the following code :
public class MainTest { public static void main(String[] args) { A[] arr = new A[] { new A() }; System.out.println((Integer[]) java.util.Arrays.stream(arr) .map(a -> a.getInt(1)) .collect(java.util.stream.Collectors.toList()) .toArray(new Integer[arr.length])); } } class A { public int getInt(int a) { return a; } }
the compiled binary crashes with the following Exception:
Exception in thread "main" java.lang.AbstractMethodError: Method MainTest$1.apply(Ljava/lang/Object;)Ljava/lang/Object; is abstract at MainTest$1.apply(MainTest.java) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at MainTest.main(MainTest.java:5)
Comments (5)
-
-
A simpler test that has the same problem:
import java.util.function.Function; public class Test { public static void main(String[] args) { map(1, e->e); } static <T, R> R map(T e, Function<? super T, R> f) { return f.apply(e); } }
-
Even simpler test:
import java.util.function.Consumer; public class L3 { public static void main(String[] args) { accept("x", e->{}); } static <T> void accept(T v, Consumer<? super T> f) { f.accept(v); } }
-
- changed status to resolved
Fix error in anonymous lambda class generation
The anonymous class implementing a lambda expression could have an illegal declaration when the lambda had a parameterized type if the parameterized type used wildcards. Wildcards are not allowed in a standalone type declaration, so the non-wildcard parameterization of the type should be used instead.
fixes
#216→ <<cset 51f94952f3c4>>
-
- removed milestone
Removing milestone: java8 (automated comment)
- Log in to comment
ExtendJ generates an anonymous class to implement the lambda expression. In this case, ExtendJ infers the type of the lambda to be
Function<? super A, ? extends Object>
, and then it generates a class implementing this type. However, it is not allowed to have wildcards as type arguments.Here is a smaller version of your test:
The bytecode for the implicitly generated anonymous lambda class:
It is surprising that this was already not covered by the lambda tests in ExtendJ's regression test suite, but I'll add this test now.