Recently, I've been doing work with interfaces and extending interfaces, as in:
public interface Superclass {
// ...
}
public interface Subclass extends Superclass {
// ...
}
I have classes which implement a third interface:
public interface DoesStuff {
Iterator<Superclass > iterator();
// ...
}
You would think that an implementation of DoesStuff could return an Iterator
public class MyClass implements DoesStuff {
// ...
private Set<Subclass > myThings = new HashSet<Subclass >();
// ...
public Iterator<Superclass > iterator() {
return myThings.iterator();
}
// ...
}
Unfortunately, the Wall of Erasure means we can't do this. Try it for yourself if you don't believe me.
So, what to do? Happily, there is a simple answer. We create an adapter that adapts the subclass iterator to the superclass iterator:
/**
* Adapts a derived class iterator to a base class.
*/
public class IteratorAdapter<B, D extends B > implements Iterator<B > {
private Iterator<D> d;
public IteratorAdapter(Iterator<D > aD) {
d = aD;
}
public boolean hasNext() {
return d.hasNext();
}
public B next() {
return d.next();
}
public void remove() {
d.remove();
}
}
The sad thing is that this shouldn't be necessary. It's trivial. It shouldn't have to be written by developers. The simplicity of this is a clear sign that we need to tear down the Wall of Erasure.
Will it happen any time soon? I hope so. Though I'm hearing talk that "erasing erasure" is probably off the table for Java 7. That would be a truly sad thing.