我遇到了一些我不理解的事情。当第二个相同的循环时,为什么不是每个循环都合法?
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
}
}
}
答案 0 :(得分:18)
由于您的实例变量private SomeInterface someInterface
未指定其泛型类型参数,因此someInterface
禁用了对泛型的所有使用。这意味着someInterface.getObjects()
具有原始返回类型List
而不是List<SomeNamedObject>
。这就是第一个例子无法编译的原因。
在第二个示例中,List<SomeNamedObject> objects = someInterface.getObjects()
为列表添加了显式类型。当您这样做时会看到警告,因为不保证类型安全。如果getObjects()
在没有类型参数的情况下被定义为List getObjects()
,则会出现这种情况。
答案 1 :(得分:3)
您应该注意,在第二个循环之前,当您对象对象时,会收到编译器警告。
Type safety: The expression of type List needs unchecked conversion to conform to
List<TestClass.SomeNamedObject>
这会告诉你,由于某种原因你的getObjects()方法返回一个非泛化的List。这解释了为什么第一个循环不能编译。
因为您忘记了您的参考资料:
private SomeInterface someInterface;
如果你不通知它,一切都会使用原始类型,包括声明方法的签名。表示它返回原始List对象而不是List&lt; SomeNamedObject&gt; 做点什么
private SomeInterface<Object> someInterface;
它应该有效。