Search code examples
javaiterableincompatibletypeerror

Parameterize iterable wrapper in Java: incompatible types error


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.


Solution

  • 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);