【发布时间】:2014-10-07 06:34:13
【问题描述】:
在研究 Effective Java 2nd Edition 的第 23 条时,我决定尝试使用构造函数来实例化对象,该构造函数具有原始集合和混合对象的参数列表。我假设编译器会发现我试图将原始类型传递给构造函数。但是,编译器仅提供未经检查的异常警告,“在调用者处,而不是被调用者处”。
该类编译良好,进一步支持 Josh Bloch 的声明,即不在新代码中使用原始类型。这个编译的事实让我有点不安。
问?如何在实例化对象之前确保类的类型安全,而不必在构造函数中手动检查对象的有效性?以下仅提供了来自“调用者... in main”的未经检查的分配警告,一个防御性的程序如何针对此进行编程。
public class RawType {
private final Collection<Example> example;
public RawType( Collection<Example> example ) {
this.example = example;
}
public Collection<Example> getExample() {
return example;
}
public static void main( String[] args ) {
Collection unsafe = new ArrayList();
unsafe.add( new Example() );
unsafe.add( new Corruption() );
unsafe.add( new Example() );
RawType rawType = new RawType( unsafe ); // Corruption
for(Object type : rawType.getExample()) {
System.out.println(type.getClass().getName()); // Mixed Classes...
}
}
static class Corruption {}
static class Example{}
}
【问题讨论】:
-
不要忽略警告以避免这种情况。
-
警告不在“被调用者”(构造函数),因为它没有任何问题。问题出在调用者处,您使用的是原始类型,而您应该使用正确的泛型类型。为了使警告也出现在被调用方,它必须说“这个构造函数/方法在其他地方没有正确使用”,这没有任何意义。
-
我明确指出,“调用者。在 main 中”考虑您正在构建一个 API 并且有人发送一个原始类型......如果没有手动验证,您如何防御性地对其进行编程。这就是问题所在。
-
我不应该担心它。每个 Java 程序员都应该知道,使用原始类型需要自担风险,如果他们的程序因此而无法运行,那是他们的错,而不是你的错。另请注意,绝大多数类/API 也不能防止原始参数。
-
“许多 API 也不能防止原始参数”......从来没有想过......很有趣。
标签: java generics type-safety raw-types