2011-10-21 25 views
5

の具体的な種類を取得し、私は次のようJavaリフレクション:実装汎用インタフェース

public class AtomEntryHandler implements ConsumingHandler<AtomEntry> 
{ 
... 
} 

のようなクラスを持っていると言うAtomEntryHandler.classのクラスオブジェクトからクラスオブジェクトAtomEntry.classを取得することが可能ですか?

私はそれが消去の可能性はないと思っていましたが、友人はそれだと言いました。

+0

あなたの友人はどのように言いましたか? –

+2

いいえ、したがって質問:-D – ekj

+0

アレックス・ギテルマンの答えはあなたのために働いていますか? –

答えて

4

インタフェースの実装の場合に基本型のパラメータを決定する方法を見つけることができませんでした。しかし、これはそれがそれに近づくのと同じくらいです。

import java.lang.reflect.*; 
public class Foo { 
    static class Bar<T> { 
    } 
    static class SubBar extends Bar<Integer> { 
    } 

    public static void main(String argv[]) { 
    ParameterizedType pt = (ParameterizedType)SubBar.class.getGenericSuperclass(); 
    Type[] t = pt.getActualTypeArguments(); 
    for (int i=0;i<t.length;i++) { 
     System.out.println(t[i]); 
    } 
    } 
} 

結果: class java.lang.Integer

8

あなただけ具体的な実装のために、インタフェースとの直接のサブクラスの両方のための一般的なタイプを得ることができます。たとえば、List<T>インスタンスがある場合、タイプ消去のためにパラメータ化された内容を知る方法がありません。コンパイル時に既知のパラメータ化された型がクラス定義に含まれている場合(たとえば、class StringList extends List<String>)、の情報を取得できます。

ParameterizedType pt = (ParameterizedType)AtomEntryHandler.class.getGenericInterfaces()[0]; 
Class atomEntryClass = (Class)pt.getActualTypeArguments()[0]; 
+2

私はdocのインタフェースについて読んでいますが、classが問題のようにパラメータ化されたインタフェースを実装していて(明示的にクラスを拡張していない場合)、 'ParameterizedType'にキャストするときに' java.lang.Object'を取得して例外をキャストします。 –

+0

'getGenericSuperclass()'を呼び出して明示的に何も拡張していない場合、または非ジェネリッククラスを拡張している場合はそうですが、 'getGenericInterfaces()'を呼び出すとクラス階層は重要ではありませんインターフェイス。 –

1

あなたはConsumingHandlerAtomEntryHandler実装のみインタフェースであり、あなたはそれだけで1型引数を取る知ることが起こる知ってしまった場合、あなたはこれを行うことができます:

interface ConsumingHandler<T> {} 

class AtomEntry {} 

class AtomEntryHandler implements ConsumingHandler<AtomEntry> 
{ 
    public static void main(String[] args) 
    { 
     Type[] interfaces = AtomEntryHandler.class.getGenericInterfaces(); 
     ParameterizedType firstInterface = (ParameterizedType) interfaces[0]; 
     Class c = (Class) firstInterface.getActualTypeArguments()[0]; 
     System.out.println(c.getName()); // prints "AtomEntry" 
    } 
} 

そうでない場合、あなたはgetGenericInterfaces()でつつくことができ、それらのactualTypeArgumentsはあなたが探しているもののようなものを見つけるまで続きます。

しかし、実際のコードでこれを行う必要がある場合は、おそらく何かがあなたのデザインに間違っているか、またはあなたが狂気の天才オブジェクトライブラリを書いているので、これらの質問に答える必要はありません。

+0

ええ、私はそれを使って遊んでいただけで、コードが必要以上に複雑になってしまいました。それが単純だったなら、それはちょうど重複を避けたでしょう。 – ekj

関連する問題