Je regardais le code Java LinkedList
et a remarqué qu'il a fait usage d'une classe imbriquée statique, Entry
.
public class LinkedList<E> ... {
...
private static class Entry<E> { ... }
}
Quelle est la raison d'utiliser une classe imbriquée statique, plutôt qu'une classe interne normale?
La seule raison pour laquelle je pouvais penser, c'est que Entry n'a pas accès aux variables d'instance, donc d'un point de vue POO, il a une meilleure encapsulation.
Mais je pensais qu'il pourrait y avoir d'autres raisons, peut-être la performance. Qu'est-ce que ça pourrait être?
Remarque. J'espère avoir mes termes corrects, je l'aurais appelé une classe interne statique, mais je pense que c'est faux: http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
Réponses:
La page Sun à laquelle vous créez un lien présente quelques différences clés entre les deux:
Il n'y a pas besoin d'
LinkedList.Entry
être classe de niveau supérieur car il est uniquement utilisé parLinkedList
(il y a d'autres interfaces qui ont également des classes imbriquées statiques nomméesEntry
, telles queMap.Entry
- même concept). Et comme il n'a pas besoin d'accéder aux membres de LinkedList, il est logique qu'il soit statique - c'est une approche beaucoup plus propre.Comme le souligne Jon Skeet , je pense que c'est une meilleure idée si vous utilisez une classe imbriquée est de commencer par qu'elle soit statique, puis de décider si elle doit vraiment être non statique en fonction de votre utilisation.
la source
#comment113712_253507
A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class
comment est-ce possible si seulement un paragraphe avant que les docs disent que:Static nested classes do not have access to other members of the enclosing class
Peut - être qu'ils aimeraient dire:A nested (non-static) class interacts with the instance members of its outer class (and other classes) just like any other top-level class
An inner class interacts with the instance members through an implicit reference to its enclosing class
et cela souligne une autre propriété intéressante denon-static inner classes
ainsi queanonymous inner classes
oulocal classes defined inside a block
: ils ne peuvent pas tous avoir unno-arg
constructeur car le compilateur ajoutera implicitement la séquence arg de chaque constructeur afin de passer une référence d'une instance de l'enveloppe classe. Assez simple.À mon avis, la question devrait être l'inverse chaque fois que vous voyez une classe interne - doit-elle vraiment être une classe interne, avec la complexité supplémentaire et la référence implicite (plutôt qu'explicite et plus claire, IMO) à une instance de la classe contenante?
Attention, je suis biaisé en tant que fan de C # - C # n'a pas l'équivalent des classes internes, bien qu'il ait des types imbriqués. Je ne peux pas encore dire que j'ai manqué des cours internes :)
la source
Il y a des problèmes de rétention de mémoire non évidents à prendre en compte ici. Puisqu'une classe interne non statique maintient une référence implicite à sa classe «externe», si une instance de la classe interne est fortement référencée, alors l'instance externe est également fortement référencée. Cela peut entraîner des grattements de tête lorsque la classe externe n'est pas récupérée, même s'il semble que rien ne la référence.
la source
Eh bien, pour une chose, les classes internes non statiques ont un champ caché supplémentaire qui pointe vers l'instance de la classe externe. Donc, si la classe Entry n'était pas statique, en plus d'avoir accès dont elle n'a pas besoin, elle porterait environ quatre pointeurs au lieu de trois.
En règle générale, je dirais que si vous définissez une classe qui est essentiellement là pour agir comme une collection de membres de données, comme une "structure" en C, envisagez de la rendre statique.
la source
La classe interne statique est utilisée dans le modèle de générateur. La classe interne statique peut instancier sa classe externe qui n'a qu'un constructeur privé. Vous pouvez donc utiliser la classe interne statique pour instancier la classe externe qui n'a qu'un constructeur privé. Vous ne pouvez pas faire de même avec la classe interne car vous devez avoir un objet de la classe externe créé avant d'accéder à la classe interne.
Cela produira x: 1
la source
La classe imbriquée statique est comme toute autre classe externe, car elle n'a pas accès aux membres de la classe externe.
Juste pour la commodité de l'emballage, nous pouvons regrouper les classes imbriquées statiques en une classe externe à des fins de lisibilité. En dehors de cela, il n'y a pas d'autre cas d'utilisation de classe imbriquée statique.
Exemple pour ce type d'utilisation, vous pouvez le trouver dans le fichier Android R.java (ressources). Le dossier Res d'Android contient des mises en page (contenant des conceptions d'écran), un dossier dessinable (contenant des images utilisées pour le projet), un dossier de valeurs (qui contient des constantes de chaîne), etc.
Sine, tous les dossiers font partie du dossier Res, l'outil Android génère un fichier R.java (ressources) qui contient en interne beaucoup de classes imbriquées statiques pour chacun de leurs dossiers internes.
Voici l'aspect et la convivialité du fichier R.java généré dans Android: Ici, ils ne sont utilisés que pour la commodité de l'emballage.
la source
Sur http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html :
la source
Exemple simple:
Si non statique, la classe ne peut pas être instanciée sauf dans une instance de la classe supérieure (donc pas dans l'exemple où main est une fonction statique)
la source
L'une des raisons de la statique par rapport à la normale est liée au chargement de classe. Vous ne pouvez pas instancier une classe interne dans le constructeur de son parent.
PS: J'ai toujours compris que «imbriqué» et «intérieur» étaient interchangeables. Il peut y avoir de subtiles nuances dans les termes, mais la plupart des développeurs Java comprendraient l'un ou l'autre.
la source
Les classes internes non statiques peuvent entraîner des fuites de mémoire tandis que la classe interne statique les protégera. Si la classe externe contient des données considérables, cela peut réduire les performances de l'application.
la source
Je ne connais pas la différence de performances, mais comme vous le dites, la classe imbriquée statique ne fait pas partie d'une instance de la classe englobante. Il semble plus simple de créer une classe imbriquée statique, sauf si vous en avez vraiment besoin pour être une classe interne.
C'est un peu comme pourquoi je rend toujours mes variables finales en Java - si elles ne sont pas finales, je sais qu'il se passe quelque chose de drôle avec elles. Si vous utilisez une classe interne au lieu d'une classe imbriquée statique, il devrait y avoir une bonne raison.
la source
L'utilisation d'une classe imbriquée statique plutôt que non statique peut économiser de l'espace dans certains cas. Par exemple: implémenter un
Comparator
dans une classe, par exemple Étudiant.Ensuite, le
static
vérifie que la classe Student n'a qu'un seul comparateur, plutôt que d'en instancier un nouveau chaque fois qu'une nouvelle instance student est créée.la source
Avantage de la classe interne -
Sans existence de classe externe, la classe interne n'existera pas.
Il existe quatre types de classes internes.
point ---
afin d'invoquer la classe interne normale dans la zone statique de la classe externe.
Outer 0=new Outer(); Outer.Inner i= O.new Inner();
afin d'invoquer la classe interne normale dans la zone d'instance de la classe externe.
Inner i=new Inner();
afin d'invoquer la classe interne normale en dehors de la classe externe.
Outer 0=new Outer(); Outer.Inner i= O.new Inner();
inside Inner class Ce pointeur sur la classe interne.
this.member-current inner class outerclassname.this--outer class
pour le modificateur applicable à la classe interne est - public, par défaut,
final,abstract,strictfp,+private,protected,static
external $ inner est le nom du nom de la classe interne.
classe interne à l'intérieur de la méthode d'instance, nous pouvons accéder au champ statique et d'instance de la classe externe.
10. classe intérieure à l'intérieur de la méthode statique, nous ne pouvons accéder qu'au champ statique de
classe externe.
la source