53 votes

Extension des classes génériques

public class MyGeneric<T, E> {}

public class Extend1<T, E> extends MyGeneric<T, E> {}

public class Extend2 extends MyGeneric<String, Object> {}

Pour autant que je suis conscient, à la fois de la sous-classes dans l'exemple ci-dessus sont valables. Je me demandais comment Java sait quand le type donné dans la super-classe vont être définis lors de la sous-classe est instanciée, et quand ils sont de véritables noms de classe (c'est à dire Comment sait-elle T, E ne sont pas des noms de classe)?

Une note de côté, est-il permis (même si rares) à l'utilisation de plus d'une lettre pour les types génériques? Que faire si (par le biais de certains sever erreur de planification) Les types de conflit avec une classe existante, par exemple

public class E{}
public class Foo<E>{}

ce qui arrive ensuite?

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

Pour répondre à la côté point, aioobe la réponse est plus claire

59voto

Joachim Sauer Points 133411

Regardons cette définition:

public class Extend1<T, E> extends MyGeneric<T, E> {}

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

  • en Extend1<T,E> vous de définir le type des arguments. Cela signifie que le type Extend1 a deux (illimité) arguments de type T et E. Cela indique au compilateur de Java que ceux qui utilisent Extend1 devez spécifier les types.
  • en extends MyGeneric<T,E> vous utilisez précédemment défini le type des arguments. Si T et E n'étaient pas connus pour être des arguments de type ici, alors T et E seraient simples références de type, c'est à dire le compilateur serait à la recherche de classes (ou des interfaces, ...) nommé T et E (et plus susceptibles de ne pas les trouver).

Oui, le type des arguments suivent les mêmes règles syntaxiques comme tout autre identifiant de Java, de sorte que vous pouvez utiliser plusieurs lettres ABC ou même des noms qui peuvent être source de confusion (à l'aide d'un argument de type appelés String est légal, mais très déroutant).

Une seule lettre type argument noms sont tout simplement un très commune de la stratégie de nommage.

22voto

aioobe Points 158466

Je me demandais comment Java sait quand le type donné dans la super-classe vont être définis lors de la sous-classe est instansiated, et quand ils sont de véritables noms de classe (c'est à dire Comment sait-elle T, E ne sont pas des noms de classe)?

Java n'a pas de soins. Si vous ne...

class MyGeneric<String> extends ArrayList<String> {
    String value;
}

est-il permis (même si rares) à l'utilisation de plus d'une lettre pour les types génériques? Que faire si (par le biais de certains sever erreur de planification) Les types de conflit avec une classe existante, par exemple

Oui, vous pouvez utiliser n'importe valide Java identificateur de paramètres de type.

Les noms peuvent être en conflit, mais Java ne pas traiter cela comme une erreur. Les identificateurs entre <...> seront toujours traités comme des paramètres de type, peu importe si l'identifiant correspond à un nom de classe.

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

class MyGeneric<String> extends java.util.ArrayList<String> {
    String value;
}

class Test {
    public static void main(String... args) throws Exception {
        MyGeneric<Integer> obj = new MyGeneric<Integer>();
        obj.value = 5;
        //          ^
        //          |
        //          '--- Assign an integer to what seems to be a String!
    }
}

Question similaire:

2voto

Bohemian Points 134107

Il n'y a aucun problème avec:

 public class E{}
public class Foo<E>{}
 

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

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