Let's assume I have some wrapper class over an iterable object. The wrapper itself is made iterable as well, bringing the functionality one level up.
public class Wrapper implements Iterable<ObjectField> {
private final InnerObject obj;
Wrapper(InnerObject obj) {
this.obj = obj;
}
@Override
public Iterator<ObjectField> iterator() {
return new FieldIterator(obj);
}
}
where ObjectField is the inner field of my wrapper object and FieldIterator is declared as
public class FieldIterator implements Iterator<ObjectField> {
private final InnerObject obj;
public FieldIterator(InnerObject obj) {
this.obj = obj;
}
@Override
public boolean hasNext() {
return obj.hasNext();
}
@Override
public ObjectField next() {
return obj.next();
}
@Override
public void remove() { obj.remove(); }
}
and the wrapper is used somethere in code as follows
for (ObjectField f : wrapper) {
// some code
}
Now I want to parameterize the wrapper with descendants of InnerObject class:
public class Wrapper<T extends InnerObject> implements Iterable<ObjectField> {
private final T obj;
Wrapper(T obj) {
this.obj = obj;
}
@Override
public Iterator<ObjectField> iterator() {
return new FieldIterator(obj);
}
}
But when I do this, the client code
for (ObjectField f : wrapper)
stops compiling, saying:
Incompatible types. Required: ObjectField, Found: java.lang.Object
Please forgive me my simple question, as I am just learning Java. I suspect that the behaviour is related to Java's type erasure, but still cannot figure out how to implement this simple pattern.
How do you declare wrapper
?
Must be like this:
Wrapper<InnerObject> wrapper = new Wrapper<>(obj);
Or like this:
Wrapper<ObjectField> wrapper = new Wrapper<>(obj);
You probably did'it like this:
Wrapper wrapper = new Wrapper(obj);