2012-04-04 66 views
1

因此,这里是我的代码:为什么我会在这个泛型类型上得到一个未经检查的强制转换警告?

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延伸可写,所以为什么我得到一个警告,当我尝试投的可写为T?而且由于我知道T扩展了Writable,是否可以安全地抑制这个警告?

回答

4

你所得到的警告,因为WritableFactories.newInstance返回一个Writable和你T延伸Writable,所以可能不是一个安全的演员。但是,由于您使用Class<T>作为您的参数newInstance,因此可以安全地禁止此警告。

这可能是更好的存储valueClassClass<T>和使用Class#cast投给你,那么你将不会有任何丑陋@SuppressWarnings挂在你的方法。

+0

良好的通话!并感谢您的快速响应。以前没有使用Class.cast,但我想我喜欢它! – sangfroid 2012-04-04 22:28:30

+0

@PaulBellora我不使用hadoop,但[参考](http://hadoop.apache.org/common/docs/current/api/org/apache/hadoop/io/WritableFactories.html#newInstance(java。 lang.Class))我发现显示'可写入'。 – Jeffrey 2012-04-05 01:25:58

+0

@Jeffrey - 我的错!我掠过太快,并假定OP使用Class#newInstance,完全缺少hadoop部分。 – 2012-04-05 01:28:33

3

所有T的是Writable,但不是所有的Writable都是T s。所以当你投WritableT,它不能确定Writable实际上 a T

例如,假设有一个S extends WritablenewInstance可能是S而不是 a T,但它仍然是Writable - 但将其转换为T会给你一个ClassCastException

+0

您复制了我的答案;) – ControlAltDel 2012-04-04 22:13:11

+0

不,StackOverflow说我的帖子是在22:12:14发布的,但是您的帖子在30秒后发布在22:12:44。这是相反的方式。 ;) – 2012-04-04 22:13:43

+0

是的,但我确定知道我首先想到它:-D – ControlAltDel 2012-04-04 22:15:33

1

所有T的是可写的,但不是所有的Writables是T的

相关问题