为什么我会在此通用类型上获得未经检查的强制转换警告?

时间:2012-04-04 22:09:40

标签: java generics types casting warnings

所以这是我的代码:

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扩展为可写,那么抑制这个警告是否安全?

3 个答案:

答案 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 WritablenewInstance可能是S不是 T,但它仍然是Writable - 但是将其投放到T会给你一个ClassCastException

答案 2 :(得分:1)

所有T都是可写的,但并非所有可写的都是T的