I would like to write an Interator like this:
class Plant { }
class Tree extends Plant { }
class Maple extends Tree { }
// Iterator class: compiler error on the word "super".
class MyIterator<T super Maple> implements Iterator<T> {
private int index = 0;
private List<Maple> list = // Get the list from an external source.
public T next() {
Maple maple = list.get(index++);
// Do some processing.
return maple;
}
// The other methods of Iterator are easy to implement.
}
Conceptually, the idea is to have an iterator that looks like it returns Trees or Plants (even though they are always Maples) without writing separate classes for each.
But the compiler doesn't like it when I generify with T super Maple
; apparently you can only generify a class using T extends Something
. Does anyone know of a good way to accomplish the same thing?
My motivation for asking is that I have a program that uses interfaces for its API. I want to have one method that returns an iterator of interfaces (for the API) and another that returns an iterator of the implementation classes (for internal use).
See: Why is there no lower bound for type parameters?
If Maple
is a Tree
and a Plant
, because it extends both, what is the point then in the super clause that you want to use? You can, by classical subtype polymorphism assign Mapple
to Object
, to Tree
or to Plant
references.
Both ? extends T
and ? super T
are wildcards, declared as type arguments to substitute a type parameter T
.
What you intend to do is define the bound of a type argument not of the type parameter. You can simply declare your type parameter as T, with no bounds, and then, when you use it, you use a wildcard as the type argument.
class MyIterator<T> implements Iterator<T> { ... }
And when you use it:
MyIterator<? super Maple> iter;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With