Reputation: 566
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
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