web-dev-qa-db-fra.com

Java Génériques, obtenez la classe <T> du paramètre générique

J'ai un cours abstrait:

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

J'ai besoin de remplir ClassT clazz; avec les enfants de RootProcessor - chaque enfant a son propre T

J'ai trouvé une seule solution, mais il faut l'argument du compilateur -Xlint:unchecked

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

Est-ce la meilleure solution? Peut-on faire la même chose sans -Xlint:unchecked?

40
Victor Mezrin

Pour ce faire, il faut passer le Class<T> jeton "où le compilateur peut le voir":

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);
    }
}

Si vous réalisez une distribution non contrôlée, mais que vous "savez ce que vous faites" et que vous voulez que le compilateur arrête de se plaindre, la bonne approche consiste à localiser les bits non sécurisés au niveau du type, mais vous savez qu'ils fonctionnent. en utilisant @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();
    }
}

(Je ne t'en voudrai pas: P)

34
millimoose

Il y a un article du même sujet: Reflecting generics

Et une classe qui l'implémente: TypeArgumentsUtils.Java

Un exemple est dans le test unitaire.

Donc si vous avez ce cours:

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

que vous obtiendriez le premier paramètre avec:

Class barClass = TypeArgumentsUtils.getFirstTypeArgument(
        RootProcessor.class, BarProcessor.class);
3
Basilios Raptis