J'apprends les génériques Java à partir d'un livre. Le livre dit que «les variables de type de classe ne sont pas valides dans les contextes statiques» et l'explique avec l'exemple suivant.
Considérons une classe générique avec des variables de type, telles que Entry. Vous ne pouvez pas utiliser les variables de type K et V avec des variables ou des méthodes statiques. Par exemple, ce qui suit ne fonctionne pas:
public class Entry<K, V> {
// Compiler error - V in static context ("Entry.this' cannot be referenced from a static context")
private static V defaultValue;
// Compiler error - V in static context ("Entry.this' cannot be referenced from a static context")
public static void setDefault(V value) {
defaultValue = value;
}
}
Après tout, l'effacement de type signifie qu'il n'y a qu'une seule variable ou méthode dans la classe Entry effacée, et non une pour chaque K et V.
Je ne comprends pas l'explication ci-dessus. J'ai essayé de créer le même code pour K également et j'ai eu les mêmes erreurs de compilation. Pourquoi le code ci-dessus est-il illégal?
3 Réponses :
Supposons que les variables statiques fonctionnent comme vous l'avez décrit ...
J'aurais pu le faire:
Entry<String, Integer>.defaultValue = 1; Entry<String, String>.defaultValue = "Hello"; System.out.println(Entry<String, Integer>.defaultValue); // 1 System.out.println(Entry<String, String>.defaultValue); // Hello
C'est ce à quoi vous vous attendez, n'est-ce pas?
Mais rappelez-vous que les variables static sont une par classe . En raison de l'effacement du type, Entry et Entry sont considérés comme la même classe. Et pour le code ci-dessus, le travail, 1 et "Hello" devrait être stocké à deux endroits différents (deux variables)! p>
V sera le type de la classe d'instanciation. Si deux classes s'instancient avec des types différents pour V , quel type serait utilisé pour accéder au champ statique qui est partagé par toutes les classes au niveau de la classe?
private static V defaultValue;
Maintenant une classe instanciée a V comme String et une autre a V comme Long.
Mais static est disponible pour toutes les classes. Laquelle serait-elle lors de l'accès?
Il s'agit de savoir pourquoi vous ne pouvez pas référencer un champ d'instance à partir d'un contexte statique. Une fois dans un contexte statique, à quelle "instance" du champ d'instance serait-elle accessible? Il ne peut pas être déterminé, donc ce n'est pas légal (et n'a pas de sens).
Les concepteurs de génériques Java ont choisi de l'implémenter en utilisant un mécanisme appelé "effacement de type". Cela signifie que les spécialisations génériques telles que Entry et Entry n'existent pas en tant que classes séparées. Les paramètres de type sont effacés.
Après avoir effacé les paramètres de type de Entry et Entry, il ne vous reste plus que Entry code> classe.
S'il était possible d'avoir une variable statique comme defaultValue , vous vous attendriez à ce que Entry soit un entier. Et vous vous attendez à ce que Entry soit une chaîne. Mais après l'effacement du type, une seule classe Entry avec une seule variable defaultValue , qui doit maintenant être à la fois Integer et String. C'est impossible. C'est pourquoi vous ne pouvez pas avoir de variable statique de type générique.
Une note intéressante. Vous pouvez passer la méthode
Ven l'ajoutant à la tête.public static void setDefault (valeur V) {...} . Impossible de le faire avec la variable de classe, mais la méthode prendra alors une référence générique.Cette question n'est pas une duplication de la question mentionnée par le modérateur.
@JavaImpatient Si vous pouvez expliquer pourquoi, n'hésitez pas à modifier votre question. Si vous pouvez me convaincre, je peux vous rouvrir la question.