Reputation: 1895
I just ran into something that I do not understand. Why isn't the for each loop below legal when the second identically one is?
public interface SomeInterface<T> {
List<SomeNamedObject> getObjects();
void doSomething(P1 p1, T p2);
}
public class SomeNamedObject {
private String text;
}
public class Clazz {
private SomeInterface someInterface;
...
public void someMethod() {
// Error Type mismatch: cannot convert from element type Object to TestClass.SomeNamedObject
for (SomeNamedObject someNamedObject : someInterface.getObjects()) {
// This loop won't compile as the someInterface.getObjects returns just a List and not a List<SomeNamedObject>
}
// Warning Type safety: The expression of type List needs unchecked
// conversion to conform to List<TestClass.SomeNamedObject>
List<SomeNamedObject> objects = someInterface.getObjects();
for (SomeNamedObject someNamedObject : objects) {
// This loop compiles
}
}
}
Upvotes: 9
Views: 860
Reputation: 848
You should note that you get a compiler warning when you asign to objects before the second loop.
Type safety: The expression of type List needs unchecked conversion to conform to
List<TestClass.SomeNamedObject>
This would have told you that for some reason your getObjects() method is returning a non generified List. Which explains why the first loop does not compile.
Because you forgot to generify your reference:
private SomeInterface someInterface;
If you dont generify it everything will use the raw type, including the signature of the declared method. Means it returns a raw List object instead of a List<SomeNamedObject> Do something like
private SomeInterface<Object> someInterface;
And it should work.
Upvotes: 3
Reputation: 66263
Because your instance variable private SomeInterface someInterface
doesn't specify its generic type parameter then all use of generics is disabled for someInterface
. This means that someInterface.getObjects()
has the raw return type List
rather than List<SomeNamedObject>
. This is the reason the first example does not compile.
In the second example List<SomeNamedObject> objects = someInterface.getObjects()
is putting in an explicit type for the list. You will see a warning when you do this though because the type safety is not guaranteed. This is the same behaviour you would see if getObjects()
was defined as just List getObjects()
without the type parameter.
Upvotes: 18