Extension de classes génériques

public class MyGeneric {} public class Extend1 extends MyGeneric {} public class Extend2 extends MyGeneric {} 

Autant que je sache, les deux sous-classes de l’exemple ci-dessus sont valides. Je me demandais comment Java sait quand les types donnés dans la superclasse vont être définis quand la sous-classe est instanciée, et quand ce sont des noms de classes réels (c.-à-d. Comment est-ce que T, E ne sont pas des noms de classes)?

Une note d’accompagnement, est-il permis (même si rare) d’utiliser plus d’une lettre pour les types génériques? Que se passe-t-il si (par une erreur de planification grave) les types entrent en conflit avec une classe existante, par exemple

 public class E{} public class Foo{} 

que se passe-t-il alors?

Edit: Merci d’avoir répondu si rapidement. Pour répondre à ma première question, la réponse de Joachim est la plus efficace.

Pour répondre à ce point, la réponse de aioobe est plus claire

Regardons cette définition:

 public class Extend1 extends MyGeneric {} 

Ici, T et E sont chacun présents deux fois et dans deux rôles différents

  • dans Extend1 vous définissez des arguments de type. Cela signifie que le type Extend1 a deux arguments de type (non Extend1 ) T et E Cela indique au compilateur Java que ceux qui utilisent Extend1 doivent spécifier les types.
  • dans extends MyGeneric vous utilisez les arguments de type définis précédemment. Si T et E n’étaient pas connus pour être des arguments de type ici, alors T et E seraient des références de type simples, c’est-à-dire que le compilateur chercherait des classes (ou interfaces, …) nommées T et E .

Oui, les arguments de type suivent les mêmes règles syntaxiques que tout autre identificateur Java, vous pouvez donc utiliser plusieurs lettres ABC ou même des noms qui peuvent porter à confusion (l’utilisation d’un argument de type Ssortingng est légal, mais extrêmement déroutant).

Les noms d’argument de type lettre unique sont simplement une stratégie de nommage très courante.

Je me demandais comment Java sait quand les types donnés dans la superclasse vont être définis lorsque la sous-classe est instanciée, et quand ils sont des noms de classes réels (c.-à-d. Comment savoir si T, E ne sont pas des noms de classes)?

Java ne fait rien. Si tu fais…

 class MyGeneric extends ArrayList { Ssortingng value; } 

Est-il permis (même si rare) d’utiliser plus d’une lettre pour les types génériques? Que se passe-t-il si (par une erreur de planification grave) les types entrent en conflit avec une classe existante, par exemple

Oui, vous pouvez utiliser n’importe quel identificateur Java valide pour les parameters de type.

Les noms peuvent être en conflit, mais Java ne traitera pas cela comme une erreur. Les identifiants entre < ... > seront toujours traités comme des parameters de type, que l'identifiant corresponde ou non à un nom de classe.

Cela peut être assez déroutant. Voici un exemple:

 class MyGeneric extends java.util.ArrayList { Ssortingng value; } class Test { public static void main(Ssortingng... args) throws Exception { MyGeneric obj = new MyGeneric(); obj.value = 5; // ^ // | // '--- Assign an integer to what seems to be a Ssortingng! } } 

Question similaire:

  • Problèmes de déballage

Il n’y a pas de problème avec:

 public class E{} public class Foo{} 

Parce que dans le contexte de Foo , E est un type.