2012-04-04 44 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的

相關問題