0

ジェネリック メソッドでは、実行時にメソッドのジェネリック型にアクセスできないようです (エラー: 型変数から選択できません)。

public <A> A get(Animal a) {
    Class ac = a.getClass();
    if(ac.isAssignableFrom(A.class)) {  // <- not working!
        return (A) a;
    } else {
        // error handling
    }
}

私がこれを行う理由は、次のようなものを安全にダウンキャストできるようにするためです。

Animal a = new Dog();
Dog d = get(a);    // <- OK
Cat c = get(a)     // <- incompatible types, caught by else block

まったく同じ問題を抱えた 9 年以上前の投稿を見つけました: https://forums.oracle.com/forums/thread.jspa?threadID=1184291

そこで、これを解決するためのアイデアは、コンストラクターで Class オブジェクトを提供し、この変数を使用して割り当て可能かどうかを確認することでした。そこに任意のクラスを配置でき、すべての優れた型チェックが役に立たなかったので、これはかなりばかげた解決策のようです...

<any>.classでは、同じ質問:実行時に の型<A>が完全にわかっているのに、なぜコンストラクターで指定する必要があるのでしょうか? の実際の型にアクセスするにはどうすればよい<A>ですか?


かなり醜い解決策を見つけました:

public <A> A get(Animal a, Class<A> clazz) {
    // same as above...
}

を提供する必要がありますClassが、ここに挿入できる唯一の有効なクラスは戻り値の型です。しかし、少なくとも今はタイプセーフです。

まったく不便です...

4

2 に答える 2

4

あなたの主張に反して、 A の型は実行時にわかりません。詳細については、型消去に関するドキュメントをご覧ください。

簡単に言えば、ランタイムは type のオブジェクトがあることを認識していますWhatever。ただし、明示的に情報を提供するかどうかをWhatever<A>区別することはできません。Whatever<B>そのため、クラス オブジェクトを提供することをお勧めします。これは、完全な型情報がわかっているコンパイル フェーズとは異なることに注意してください。

于 2012-11-13T16:44:12.373 に答える
1

実行時にジェネリック型を選択することはできません。

考えられる解決策については、こちらを参照してください:実行時にジェネリック型パラメーターにアクセスしますか?

于 2012-11-13T16:45:43.083 に答える