2016-07-02 6 views
-1

ジェネリックベクターのキャストメソッドを使用するにはどうすればよいですか?私が考えたのは、(Vector<T>).class.cast(getDates());(Vector<a_typeClass>).class.cast(getDates());のようなパターンですが、動作しません。回避策は、すべての要素を循環させることです。しかしジェネリックベクターにキャストを使用する方法が必要です。Generics Vectorのcast()メソッドの使用方法<T>

(私はAPIを拡張していますので、はい、私は、ベクトルを使用する必要があります)

編集:これは、はるかに複雑なコードのほんの一部です。タイプチェックのためキャストは失敗しません:if (Date.class.isAssignableFrom(a_typeClass))。私はまた、nullのサンプルをチェックアウトしなかった。 Eclipseはタイプチェックパターンを認識していないため、エラーType mismatch: cannot convert from Vector<Date> to Vector<T>が発生しています。

を編集します。サンプルでは、​​他の方法でisAssignableFromを使用しました。前にあったDate.class.isAssignableFrom(a_typeClass)は今やa_typeClass.equals(Date.class)です。しかし、私は(Vector<T>)キャストを使用しなければならない、私はそれを使用しない場合、コンパイルエラーType mismatch: cannot convert from Vector<Date> to Vector<T>が発生します。 davmacとJB Nizetに感謝します。

サンプル:サンプルの周り

public class VectorCast { 

    @SuppressWarnings("unchecked") 
    public <T> Vector<T> getVector1(Class<T> a_typeClass) { 
     Vector<T> returnValues = new Vector<>(); 
     if (a_typeClass.equals(Date.class)) { 
      returnValues = (Vector<T>) getDates(); 

      // Not working 
      // return (Vector<T>).class.cast(getDates()); 
      // return (Vector<a_typeClass>).class.cast(getDates()); 
     } 

     return returnValues; 
    } 

    public Vector<Date> getDates() { 
     // Just dummy Values 
     return new Vector<Date>(Arrays.asList(new Date(0), new Date())); 
    } 

    public static void main(String[] args) { 
     VectorCast vectorCast = new VectorCast(); 
     System.out.println(vectorCast.getVector1(Date.class)); 
    } 
} 

が仕事:

public <T> Vector<T> getVector2(Class<T> a_typeClass) { 
    Vector<T> returnValues = new Vector<>(); 

    if (a_typeClass.equals(Date.class)) { 
     for (Date date : getDates()) { 
      returnValues.add(a_typeClass.cast(date)); 
     } 
    } 

    return returnValues; 
} 
+0

ベクトルを持っていて、ベクトルに変換したいのですが、それは正しいですか? Foosの1つがBarでない場合はどうなりますか? –

+0

彼らは常に正しいタイプです。私はユーザが望むベクターでチェックします。: '(Date.class.isAssignableFrom(a_typeClass))'と 'public Vector getDates()'はいつも 'Vector ' –

+0

を返します。あなたがしていることはうまくいかないので、質問してください。私が求めているのは、あなたは何をしたいのですか? Foosの1つがBarでない場合、コードはどのようにすべきですか? –

答えて

0

だから、私が正しく理解していれば、あなたはあなたの方法は、既存のVector<Date>を返すようにしたいが、Vector<T>としてクラスには、として渡された場合引数がDate.classであるか、または引数として渡されたクラスがDate.classでない場合は空のベクトルです。とにかく、それはかなり奇妙な要件です。

実行時に、a_typeClassDateに割り当てられることを確認します。しかし、コンパイラはそれについての手がかりがありません。 Tは、Dateよりもさらに別のタイプであり、Vector<T>は、Vector<Date>よりもさらに別のタイプです。あなたはそれを幸せにするためにキャストが必要です。

でも、あなたの小切手は間違っています。安全のためには、a_typeClassと等しく、からDate.classとなるはずです。私はあなたのメソッドを引数としてjava.sql.Timestamp.classと呼ぶことができ、あなたのメソッドはVector<Date>を喜んでVector<Timestamp>として返します。したがって、呼び出し側は、VectorにTimestampインスタンスが含まれると予想し、返されたVectorで最初に呼び出されるget()呼び出しはClassCastExceptionで失敗します。

だから、何を行うことができますすることa_typeClassDate.class等しいであることを確認して、コードはコンパイルするために絶対に必要であるが、キャストを残し、そして常に未チェックとなりますので、警告を発しています。

+0

あなたはタイプチェックについて正しいです。私は質問でそれを変更しました。私が 'getVector1(Date.class)'を呼び出すとします。 'a_typeClass = Date.class'の場合、Tは' Date'型であり、メソッドの戻り値の型は 'Vector 'となります。 'a_typeClass.equals(Date.class)'をチェックすると戻り値の型は 'Vector 'でなければなりませんが、まだキャストが必要です。 –

0

クラスリテラルは生のクラスのみのためではありません。

 Class<Vector<T>> c = (Class<Vector<T>>)(Object) Vector.class; 
     return c.cast(getDates()); 

これは、あなたが現在持っているキャストよりも明確ではありません。

Javaのコンパイル時型チェックでは制御フローが考慮されないという問題があります。あなたが持っているコードパターンは、(おそらくこの理由から)Javaでは珍しいです。手動型チェックに基づいて異なる動作をさせるようにリファクタリングを検討してください。

+0

あなたの解決策は動作していますが、 'タイプセーフティ:オブジェクトからクラスへのキャストをチェックしないでください。>' –

+0

のために、まだ@SuppressWarnings( "unchecked") 'が必要です。あなたの現在のデザインでこれを回避する方法はありません。異なるコードパターンの使用を検討してください。 – davmac

関連する問題