6 votes

Java : Pourquoi suis-je capable d'avoir une référence à un tableau non nul de types concrets paramétrés ?

J'ai été surpris, mais ... ça se compile :

public <T extends Database> ColMetaData<T>[] getTableColumnsAsEnums() {
            Class<? extends ColMetaData> cls = this.columnsEnumToken();
            return cls.<ColMetaData<T>[]>getEnumConstants(); }

Voici la méthode pour columnsEnumToken :

// Returns a class token for an enum class
public Class<? extends ColMetaData> columnsEnumToken()  { 
    return this.e_colsToken; 
}

(Je suppose que je peux voir pourquoi la deuxième ligne ci-dessous ne compile pas)

Quelques questions :

  • Cette méthode est-elle "sûre" ?

  • Pourquoi cette ligne compile-t-elle :

    Class<? extends ColMetaData> cls = this.columnsEnumToken();

    Mais celui-ci ne compile pas à cause de types incompatibles :

    Class<? extends ColMetaData<T>> cls = this.columnsEnumToken();

  • Pourquoi est-il légal pour la méthode getTableColumnsAsEnums() pour retourner un tableau d'un type concret paramétré, ColMetaData<T>[] . J'avais pensé qu'ils étaient strictement interdits parce qu'il n'y avait aucun moyen de les faire fonctionner de manière sûre au moment de l'exécution.

2voto

bayou.io Points 3680

Classe

Théoriquement, une classe ne peut pas représenter un type paramétré. Par exemple, il n'existe pas de classe pour List<String> Vous ne devez donc pas écrire Class<List<String>> mais seulement Class<List> .

Cependant Class<? extends List<String>> pourrait avoir un sens. Par exemple, si nous avons

    public class MyStringList extends ArrayList<String>{}

MyStringList.class est un Class<MyStringList> qui est un Class<? extends List<String>>

Tableau générique

Il n'y a rien de mal à utiliser un type de tableau générique, c'est juste que Java nous interdit d'en instancier... Mais la raison n'est pas très convaincante. Vous pouvez tout simplement en créer un par le biais de castings, tant que vous savez que c'est sûr.

En fait, il existe une méthode directe en Java pour créer un tableau générique. Lorsque nous appelons une méthode avec des varargues X... , un X[] sera créé - et X peut être de n'importe quel type.

Affectation compatible

Apparemment, pour une raison de rétrocompatibilité, nous pouvons attribuer une valeur de List[] à List<String>[] . C'est pourquoi vous pouvez renvoyer un ColMetaData[] alors que le type de retour est ColMetaData<T>[] .

1voto

jpmc26 Points 3364

Pensez à ce que ColMetaData<T>[] représente. En Java, les génériques sont strictement une question de temps de compilation. Au moment de l'exécution, ils cessent d'exister. Donc ce que vous dites réellement au runtime est que vous avez un tableau de ColMetaData qui est en effet un type concret. C'est différent, cependant, de l'utilisation d'un type arbitraire pour le tableau. Le type du tableau est toujours ColMetaData et Java peut le déterminer au moment de la compilation. Il suffit alors au compilateur de vérifier que les instances que vous stockez utilisent le bon type générique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X