Steve Brandli
Steve Brandli

Reputation: 566

Error compiling lambda with bounded generic

The following is a contrived, self-contained example I created to demonstrate a problem I'm having with a much more complicated program:

public class MyTest {
    public static void main(String[] args) {
        SubObject[] array = new SubObject[5];
        Iterator<? extends SuperObject> iterator 
                = Arrays.asList((SuperObject[]) array).iterator();
        Iterable<? extends SuperObject> iterable = () -> iterator;
    }
}

class SuperObject {};

class SubObject extends SuperObject{};

This does not compile:

MyTest.java:9: error: incompatible types: bad return type in lambda expression
        Iterable<? extends SuperObject> iterable = () -> iterator;
                                                         ^
    Iterator<CAP#1> cannot be converted to Iterator<SuperObject>
  where CAP#1 is a fresh type-variable:
    CAP#1 extends SuperObject from capture of ? extends SuperObject

I know I could simplify the generics, replacing <? extends SuperObject> with <SuperObject>. But this would defeat my purpose in the larger program. Why this error?

Upvotes: 2

Views: 68

Answers (1)

Steve Brandli
Steve Brandli

Reputation: 566

Thanks to @Radiodef's comment, I was able to figure this out. The trick, as explained in https://docs.oracle.com/javase/tutorial/java/generics/capture.html, is to use a helper function:

public class MyTest4 {
    public static void main(String[] args) {
        SubObject[] array = new SubObject[5];
        Iterator<? extends SuperObject> iterator
                = Arrays.asList((SuperObject[]) array).iterator();
        Iterable<? extends SuperObject> iterable = getIterable(iterator);
    }

    static <T> Iterable<T> getIterable(Iterator<T> iterator) {
        return () -> iterator;
    }

}

class SuperObject {};

class SubObject extends SuperObject{};

Upvotes: 2

Related Questions