在研究有效的Java第2版第23项时,我决定尝试使用构造函数实例化一个对象,该构造函数具有带有混合对象参数列表的原始集合。我假设编译器会发现我试图将一个原始类型传递给构造函数。但是,编译器只提供未经检查的异常警告,“在调用方,而不是被调用方”。
这个类编译得很好,进一步支持了乔希·布洛赫( Josh Bloch )的语句,以便在新代码中不使用原始类型。这个汇编的事实让我有点不安。
问:如何在实例化对象之前确保类的类型安全性,而不必手动检查构造函数中的对象有效性?以下只提供了来自“调用者.主要”的未经检查的赋值警告,您如何才能对此进行防御编程。
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{}
}
发布于 2014-10-06 22:52:37
下面的行进行编译,但也会生成警告。
Collection unsafe = new ArrayList(); // RAW type
unsafe.add(1); // no compile time error (just warning)
Collection<String> example = unsafe; // assign RAW type to parametrized type
example.add(1); // compile time error
最好使用泛型集合来避免这种情况,然后在其中添加值。从不混合未加工和参数化类型。
请看下面的代码:
Collection<Integer> unsafe = new ArrayList<Integer>();
unsafe.add(1);
Collection<String> example = unsafe; // compile time error
如果无法避免原始类型,那么在构造函数中使用下面的代码:
Collection unsafe = new ArrayList();
unsafe.add(1);
unsafe.add("hello");
// in the constructor, just add String values from the unsafe collection
Collection<String> example = new ArrayList<String>();
for(Object value:unsafe){
if(value instanceof String){
example.add((String)value);
}
}
发布于 2014-10-06 22:43:01
为了使java泛型与引入之前编写的代码兼容,您可以在任何需要类型化集合的地方使用非类型化集合。因此,集合(没有类型参数)可以传递给期望集合的构造函数。
因此,在回答您的集合时,只有在将对象添加到未键入的函数中时,才能小心。如果您想要运行时sadfety,可以在从集合中提取对象类型时手动验证它们的类型。
https://stackoverflow.com/questions/26229918
复制相似问题