49

私は抽象クラスを持っています:

public abstract class RootProcessor<T> {
    Class<T> clazz;
}

ClassT clazz;の子で満たす必要がありますRootProcessor- すべての子には独自の子がありますT

解決策は 1 つしか見つかりませんでしたが、コンパイラの引数が必要です-Xlint:unchecked

public RootProcessor(){
    this.clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}

これが最善の解決策ですか?なしで同じことができ-Xlint:uncheckedますか?

4

2 に答える 2

39

タイプセーフですが、これを行う定型的な方法は、Class<T>「コンパイラがそれを見ることができる場所」にトークンを渡すことです:

public abstract class RootProcessor<T> {
    Class<T> clazz;

    protected RootProcessor<T>(Class<T> clazz) {
        this.clazz = clazz;
    }
}

public class FooProcessor extends RootProcessor<Foo> {
    public FooProcessor() {
        super(Foo.class);
    }
}

チェックされていないキャストを行っているが、「自分が何をしているのかを知っている」ため、コンパイラに文句を言うのをやめさせたい場合、正しいアプローチは、タイプセーフではないビットをローカライズすることです。使用@SuppressWarnings:

public abstract class RootProcessor<T> {
    Class<T> clazz;
    { initClazz(); }

    @SuppressWarnings("unchecked")
    private void initClazz() {
        // the usual verbiage you already have in your question
        this.clazz = this.getClass().getGenericSuperclass().yadda().blah();
    }
}

(私はあなたに対してこれを保持しません:P)

于 2013-05-28T18:55:11.997 に答える
3

同じ件名の投稿があります: Reflecting generics

そしてそれを実装するクラス: TypeArgumentsUtils.java

例は単体テストにあります。

したがって、このクラスがある場合:

public class BarProcessor extends RootProcessor<Bar> {
    public BarProcessor() {
    }
}

次のように最初のパラメーターを取得するよりも:

Class barClass = TypeArgumentsUtils.getFirstTypeArgument(
        RootProcessor.class, BarProcessor.class);
于 2015-06-09T15:40:05.137 に答える