2012-04-04 14 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.newInstanceWritableを返し、それ安全キャストではないかもしれませんので、あなたのTは、Writableを拡張するので、あなたは警告を得ています。ただし、newInstanceの引数としてClass<T>を使用しているため、この警告を抑制することは安全です。

Class<T>としてvalueClassを格納する方が良いと、あなたはあなたの方法上の任意の醜い@SuppressWarningsハングを持っていない、あなたのためにキャストするClass#castを使用する場合があります。

+0

いいですよね!迅速な対応に感謝します。前にClass.castを使用していないが、私はそれが好きだと思う! – sangfroid

+0

@PaulBellora私はhadoopを使用しませんが、[参照](http://hadoop.apache.org/common/docs/current/api/org/apache/hadoop/io/WritableFactories.html#newInstance(java。 lang.Class))私は「Writable」と判明しました。 – Jeffrey

+0

@ジェフリー - 私の間違い!私はあまりにも速くスキミングし、OPがClass#newInstanceを使用していると仮定し、hadoop部分を完全に欠いていました。 –

3

すべてTWritableですが、すべてではありませんWritableTです。したがって、WritableTにキャストすると、Writableであることが実際にはであり、Tであることがわかりません。

たとえば、S extends Writableがあるとします。 newInstanceSでなく、Tであるかもしれませんが、それでもWritableになりますが、TにキャストするとClassCastExceptionになります。

+0

私の答えをコピーしました;) – ControlAltDel

+0

いいえ、StackOverflowは22:12:14に掲載されましたが、30秒後に22:12:44に投稿されました。それは別の方法です。 ;) –

+0

はい、私はそれが最初に考えたことを確かに知っています:-D – ControlAltDel

1

すべてのTさんは書き込み可能ですが、すべてのWritablesはTさん

関連する問題