Reputation: 431
I have this code:
public class UndirectedGraphImpl<N> {
[...]
public Iterator<Edge<N>> adj(N v) {
return new AdjIterator(v);
}
private class AdjIterator implements Iterator<Edge<N>> {
[...]
}
public static void main(String[]args) {
Graph<Integer> g = new UndirectedGraphImpl<Integer>();
[...]
Iterator<Edge<Integer>> it = g.adj(4);
}
}
At compile time I get this error:
error: incompatible types
Iterator<Edge<Integer>> it = g.adj(4);
^
required: Iterator<Edge<Integer>>
found: Iterator<CAP#1>
where CAP#1 is a fresh type-variable:
CAP#1 extends Edge<Integer> from capture of ? extends Edge<Integer>
If I replace that line with
Iterator<Edge<Integer>> it = (Iterator<Edge<Integer>>)g.adj(4);
then I get an unchecked cast warning, but I don't understand why the compiler capture that "? extends Edge<Integer>". Someone con explain me what it happens and how to fix this?
EDIT: This is the Graph interface implemented by UndirectedGraphImpl class
public interface Graph<N> extends Iterable<N> {
[...]
Iterator<? extends Edge<N>> adj(N v);
[...]
}
Upvotes: 1
Views: 215
Reputation: 39461
The problem is that you're returning the type Iterator<? extends Edge<Integer>>
, but you're trying to assign it to a variable of type Iterator<Edge<Integer>>
.
The CAP thing you see comes from the process of capture conversion, which essentially tries to remove wildcards from returned types. But in this case they're still incompatible.
Capture conversion is defined in section 5.1.10 of the JLS in case you're interested in seeing the details.
Upvotes: 2