2013-05-22 20 views
5

コンパイル型パラメータに不明でジェネリック型のオブジェクトを作成します。Javaは私がジェネリッククラス持っ

:例えばメソッドを取得

class Field<T> { } 

そして(タイプIは、実行時にのみ知っている)他のいくつかのクラスの多くとは

class A{ 
     public Date getDate(); 
     public String getName(); 
     public Integer getNumber(); 
    } 

すべてのgetメソッドに対してクラスFieldのインスタンスを作成したいと考えています。Tは、これらのgetメソッドの戻り値の型と同じです。この例では、Field<Date>,Field<String>,Field<Integer>です。

誰でも手伝いできますか?

+2

あなたはリフレクション経由でこれをやろうとしている、実行時に、ジェネリック型は全く関係ない場合。あなたはジェネリックパラメータなしでそれを行うこともできます。 –

+0

あなたは何をしようとしているのか分かりません。コンパイルされていなくても、達成しようとしていることを示す完全なコード例を記述してください。 – erickson

+0

反射はこの使用例には適合しません。ゲッターを取得するメソッドを直接公開するイントロスペクションの使用を検討してください。 –

答えて

2

リフレクションは、通常、実行時にしかわからないものに対して使用します。ジェネリックス情報はコンパイル時に消去されます。したがって、2つを混在させることは可能ですが、一般的ではありません。

すべてのgetメソッドに対して、Fieldクラスのインスタンスを作成します.Tは、これらのgetメソッドの戻り値の型と同じです。この例では、フィールド、フィールド、フィールド。

は文字通りあなたの質問に答えるために:

Field<Date> dateField = new Field<Date>(); 
Field<String> nameField = new Field<String>(); 
Field<Integer> numberField = new Field<Integer>(); 
1

ジェネリックはコンパイル時にチェックされ、クラスAの宣言されたメソッドの戻り値の型は(リフレクションを介して)しか取得できないので、ジェネリック型はこの場合ジェネリック型のフィールドを作成できるとは思いません。ランタイム。

+0

を使用すると、不明なクラスのリストを作成する唯一の方法はList ですが、これはあまり役に立ちません。 – pad

1

、ゲッターを得る反射するのではなくイントロスペクションを使用することを検討するには:それは、この目的のために意図されました!

ゲッターを自動的に取得するコードです。注意して、getClass()getterも取得します!

for(PropertyDescriptor descriptor :Introspector.getBeanInfo(A.class).getPropertyDescriptors()){ 
    System.out.println("Getter method :" + descriptor.getReadMethod()); 
    System.out.println("Return type : " + descriptor.getReadMethod().getReturnType()); 
    Class<?> c=descriptor.getReadMethod().getReturnType(); 
} 

}

出力:

Getter method :public final native java.lang.Class java.lang.Object.getClass() 
Return type : class java.lang.Class 
Getter method :public java.util.Date A.getDate() 
Return type : class java.util.Date 
Getter method :public java.lang.String A.getName() 
Return type : class java.lang.String 
Getter method :public java.lang.Integer A.getNumber() 
Return type : class java.lang.Integer 

その後、あなたは簡単にそれらのゲッターのそれぞれのフィールドを作成することができます。ジェネリック型の場合は、コンパイラの注釈の代わりに、実際の実行時の型チェックなど、ジェネリック医薬品の

+0

またはCommons Beanutilsを使用してください。 –

2
class Field<T> { 
    T value; 
    Field(T value) {this.value = value;} 
} 


class A{ 
    Date date; 
    public Field<Date> getDate() { 
     return new Field<Date>(date); 
    } 

    //etc.... 
} 

だと思う...それは本当に、実行時には意味がありませんが、コードジェネレータでこれを使用することも可能です。コンパイルされたコードは単純に静的なキャストを持ち、ジェネリック型のチェックは一切行いません。ジェネリックの機能は、Sunが「型消去」と呼んでいたものを使用して、古いJVMとのランタイム互換性を提供するために、コンパイラに一種のタックです。ここではそれについていくつかの良い読書は次のとおりです。

http://docs.oracle.com/javase/tutorial/java/generics/erasure.html