7
votes

Puis-je utiliser le champ de classe sur une instance ArrayList en Java?

J'ai ce code, qui compile: xxx

puis j'ai essayé xxx

qui ne compile pas.

Je suis nouveau à la programmation Java (venu de C #) et j'ai pensé que t.class est un équivalent exact de typeof (t) in c #. Apparemment, il y a quelque chose de très basique que je ne comprends pas, alors ma question est ce qui ne va pas avec ArrayList .Class et n'est-ce que je n'ai pas d'autre choix, mais utilisez Nouveau Typeoken > () {} .getType () à la place? Y a-t-il une forme plus courte (plus agréable, saner)?

merci.


0 commentaires

4 Réponses :


12
votes

Malheureusement (?) Java implémente des génériques utilisant Effacement de type .

Cela signifie qu'il n'y a pas de construction pour obtenir le type générique et à l'exécution de votre arraylist ne stocke réellement que des objets.

être exact, les génériques de Java sont une construction de compilation unique. Ils garantissent la sécurité de type à la compilation uniquement.

EDIT: Je viens de remarquer ce bit de code - xxx

Il s'agit d'une solution de contournement pour les limitations de l'effacement de type. Les informations de type sont conservées si vous étendez une classe générique avec un type spécifique. Par exemple: xxx

dans votre exemple, vous étendez de manière tritive la classe typé / code>, faisant générer le compilateur de générer une classe interne anonyme < / em> qui contient les informations de type. La mise en œuvre de typetoken.getype () utilisera la réflexion pour vous donner cette information de type.

Edit2: Pour une explication plus détaillée, consultez Reflétant des génériques .


2 commentaires

En fait, l'exemple que vous avez donné ci-dessus est considéré comme un modèle antérieur appelé pseudo -typedf antipattern .


@Emil Votre lien entrevoir comment il s'agit d'un anti-motif d'étendre une classe pour rendre la déclaration des génériques plus courte. Je faisais référence à Reflétant des génériques qui est différent dans un but. Merci de l'avoir pointé sur le bouton StringList ne doit pas être utilisé!



1
votes

Votre premier échantillon de code crée une sous-classe anonyme de Typeoken complète avec des fixations génériques concrètes. Le type retourné sera une instance de classe . Mais méfiez-vous, car xxx

retournera false!

dans votre deuxième échantillon de code, vous essayez de faire quelque chose que Java ne prend pas en charge à cause de la façon dont les génériques sont des génériques mis en œuvre avec effacement de type. Il n'y a pas de classe qui représente une arraylist dont le paramètre générique est lié ... à partir du point de vue du compilateur AN ArrayList est une arrayliste quel que soit Le type générique, de sorte que l'expression ne compile pas.

Il est possible qu'aucun code de code ne fonctionne tout à fait juste. Si vous devez jouer des classes avec des paramètres génériques, vous voudrez peut-être examiner GentyRef , Ce que j'ai trouvé très utile pour simplifier l'API de demander aux types de questions que vous essayez d'obtenir des réponses.


0 commentaires

1
votes

À propos de la construction ".class", ce n'est pas un opérateur ni un membre d'instance, il est en fait un moyen de dire à la langue "aller et de trouver l'objet de classe pour ce nom de classe avant le point". Est une façon de construire littéraux de classe .

Comme spécifié dans la JLE, Section 15.8 .2 , le compilateur se plaindre si vous essayez de l'utiliser avec un type paramétré (entre autres).


0 commentaires

0
votes

L'exemple donné par Leader128 est considéré comme un anti-motif appelé pseudo-typledef anticipattern est l'alternative:

class TokenUtil{
   public static <T> TypeToken<T> newTypeToken(){
   return new TypeToken<T>();
   }
  public static void main(String[] args) {
    TypeToken<ArrayList<ServerTask>> typeTok = TokenUtil.newTypeToken();
    Type type = typeTok.getType();
   }

}


1 commentaires

Salut Emil, l'exemple que j'ai donné n'était pas une solution, mais une explication de la manière dont les informations de type générique ne sont pas effacées si la classe enfant n'est pas générique. Veuillez consulter ce lien pour une bibliothèque implémentation du Typeoken Classe qui vous permet d'obtenir des informations de type de paramètres génériques à l'aide de ce mécanisme - je soupçonne que l'OP utilise ceci ou quelque chose de similaire.