Issue with lambdas

Issue #216 resolved
Michael Chonewicz created an issue

When using a lambda, like in the following code :

public class MainTest {
    public static void main(String[] args) {
        A[] arr = new A[] { new A() };

                .map(a -> a.getInt(1))
                .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(
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(
    at MainTest.main(

Comments (5)

  1. Jesper Öqvist

    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:

    import java.util.*;
    public class L1 {
      public static void main(String[] args) {
        Collection<Integer> e = new LinkedList<>();
            .map(a -> a)

    The bytecode for the implicitly generated anonymous lambda class:

    Compiled from ""
    class L1$1 implements java.util.function.Function<? super java.lang.Integer, ? extends java.lang.Object> {
      L1$1() throws ;
           0: aload_0       
           1: invokespecial #12                 // Method java/lang/Object."<init>":()V
           4: return        
      public java.lang.Object apply(java.lang.Integer) throws ;
           0: aload_1       
           1: areturn       

    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.

  2. Jesper Öqvist

    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);
  3. Jesper Öqvist

    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) {
  4. Jesper Öqvist

    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>>

  5. Log in to comment