0

以下に示すように。クラスの説明から明らかなように、任意のSerializable型にバインドできるPropertyという名前のクラスを作成しています。

Tこれで、プロパティの値は、コンパイル中に型になるように自動バインドされます。

実行時に値のオブジェクトを Class getType()返す必要があるメソッドを実装したい、つまりClass

Property<String> p = new Property<String>();

Class<String> cl = p.getType(); 

ここでは、clがString.classであることを期待しています。もちろん、1つの方法は次のとおりです。

return value == null ? null : value.getClass();

問題は、返される型に反映されず、生の型のClassオブジェクトを返すことです。理想的にはタイプにしたいClass<String>

public class Property<T extends Serializable> implements Serializable {

    private T value = null ;
    private String name = null ;
    private boolean dirty = false ;
    private Entity parent = null ;

    public Class getType() {
        // Here I want to determine the type of T that this object is bound to ?
        return class; 
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value; 
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isDirty() {
        return dirty;
    }

    public void setDirty(boolean dirty) {
        this.dirty = dirty;
    }

    public Entity getParent() {
        return parent;
    }

    public void setParent(Entity parent) {
        this.parent = parent;
    }
}
4

3 に答える 3

6

要するに、実行時に型がすでに消去されているため、できません。

ただし、これを行うことができます(関連するコードのみに省略されています):

public class Property<T extends Serializable> implements Serializable {

    private T value = null;
    private final Class<T> clazz;

    // The constructor requires an instance of the Class<T>
    public Property(Class<T> clazz) { 
        this.clazz = clazz;
    }

    // Return a typed Class object
    public Class<T> getType() {     
         return clazz;  // echo back a typed Class object pass to the constructor
    }

Class<T>コンストラクターに渡されるオブジェクトは、一般に「型トークン」と呼ばれます。

于 2012-08-15T09:37:22.907 に答える
1

type eraserが原因で、あなたがやっている方法は不可能です。結果の 1 つは、型パラメーターのインスタンス化に使用される型を実行時に直接決定できないことです。

いくつかの代替手段を次に示します。

1) getClass() を使用して、プロパティのの型を取得します。

    public Class getType() {
        return value.getClass();
    }

Class2) T の実際の型のオブジェクトをコンストラクターのパラメーターとして明示的に渡します。Class一般的な型付けは、誤って間違ったオブジェクトを渡すことができないことを意味することに注意してください

    private T value = null;
    private Class<T> type;

    public Property(Class<T> type) { this.type = type; }

    public Class<T> getType() { this.type; }

Property クラスを具体化する別のアプローチ (設計の観点からはおそらくここでは機能しない) があります。例えば

    public class IntegerProperty extends Property<Integer> {
        public Class getType() {
            returns Integer.class;
        }
    }

これには、匿名クラスのジェネリック クラスのサブクラス、および/または を介し​​て型パラメーターにアクセスする巧妙なバリエーションがありますgetClass().getTypeParameters()。ただし、このgetTypeParameters()アプローチは、型パラメーターの特定の型を持つジェネリック クラスを拡張した場合にのみ機能することに注意してください。

于 2012-08-15T09:41:47.727 に答える
1

メソッドを書くことができます

public Class<? extends T> getType() {
    return value == null ? null : value.getClass();
}

これは の実行時型を返し、valueコンパイル時に、返されたクラスに関するできるだけ多くの情報を提供します。それはTまたは のサブクラスになりTます。

常に を返したい場合はClass<T>、 @Bohemian が説明するように、クラスをランタイム引数として提供する必要があります。型消去のため、ジェネリック クラスの型引数は実行時に使用できません。

于 2012-08-15T09:39:50.860 に答える