所以这是我的代码:
public class SetWritable<T extends Writable> implements Writable {
private Class<? extends Writable> valueClass;
private Set<T> values;
public SetWritable(Class<T> valueClass) {
this.valueClass = valueClass;
this.values = new HashSet<T>();
}
public void readFields(DataInput in) throws IOException {
values = new HashSet<T>();
int len = in.readInt();
for (int i = 0; i < len; i++) {
//this line is where I get the warning
//FYI, WritableFactories.newInstance returns an instance of Writable
T value = (T) WritableFactories.newInstance(valueClass);
value.readFields(in);
values.add(value);
}
}
}
令我感到困惑的是:我断言T扩展了Writable,所以当我尝试将Writable转换为T时,为什么会收到警告?既然我知道T扩展为可写,那么抑制这个警告是否安全?
答案 0 :(得分:4)
您收到警告,因为WritableFactories.newInstance
返回Writable
而您的T
延伸 Writable
,因此可能会不是一个安全的演员。但是,由于您使用Class<T>
作为newInstance
的参数,因此可以安全地取消此警告。
最好将valueClass
存储为Class<T>
并使用Class#cast
为您投射,然后您的方法不会有任何丑陋的@SuppressWarnings
。
答案 1 :(得分:3)
所有T
都是Writable
,但并非所有Writable
都是T
。因此,当您将Writable
投射到T
时,无法确定Writable
实际是T
。
例如,假设有一个S extends Writable
。 newInstance
可能是S
而不是 T
,但它仍然是Writable
- 但是将其投放到T
会给你一个ClassCastException
。
答案 2 :(得分:1)
所有T都是可写的,但并非所有可写的都是T的