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
}
}
}
Because your instance variable
private SomeInterface someInterfacedoesn’t specify its generic type parameter then all use of generics is disabled forsomeInterface. This means thatsomeInterface.getObjects()has the raw return typeListrather thanList<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 ifgetObjects()was defined as justList getObjects()without the type parameter.