Shilad Sen
Shilad Sen

Reputation: 114

Supporting both interfaces and classes in generic iterable

I'm trying to write an interface that is iterable and supports multiple levels of abstraction. I'm having trouble correctly defining the interface.

I've declared the following interfaces and classes (a toy example):

public interface A {}

public class B implements A {}

public interface C <T extends A> extends Iterable<T> {}

public class D implements C<B> {
    public Iterator<B> iterator() { ... }
}

The following works:

D d = new D();
for (A a : d) {}
for (B b : d) {}

But the following does not compile. Java says the for-each loop variable should be of type Object.

C c = new D();
for (B b : c) {}

I know I can cast to appease the compiler in the second example, but that seems yucky. Is there any way to declare interface C and subclass D so that I can support both iteration scenarios, or is that not possible? Thanks!

Upvotes: 2

Views: 36

Answers (1)

rgettman
rgettman

Reputation: 178253

You're using the raw form of the C interface when you assign the new D to c. Using the raw form of the interface forces type erasure on everything in the interface, meaning that the Iterator returned in the foreach loop returns Objects, not Bs.

But C takes a type argument that must still be supplied, even if D isn't itself generic. Try

C<B> c = new D();

Upvotes: 5

Related Questions