240 votes

Classe imbriquée statique en Java, pourquoi?

J'étais en train de regarder le code Java pour LinkedList et a remarqué qu'il fait usage d'une statique de la classe imbriquée, Entry.

public class LinkedList<E> ... {
...

 private static class Entry<E> { ... }

}

Quelle est la raison de l'utilisation d'une statique de la classe imbriquée, plutôt que la normale intérieure de la classe?

La seule raison pour laquelle je pouvais penser était que l'Entrée n'a pas accès aux variables d'instance, donc, à partir d'une OOP point de vue, il a une meilleure encapsulation.

Mais j'ai pensé qu'il pourrait y avoir d'autres raisons, peut-être la performance. Ce qui pourrait-il être?

Remarque. J'espère que j'ai mes conditions correctes, je l'aurais appelé ça un statique à l'intérieur de la classe, mais je pense que c'est faux: http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

290voto

matt b Points 73770

Le Soleil de la page que vous liez a quelques différences clés entre les deux:

Une classe imbriquée est un membre de sa classe englobante. Non statique classes imbriquées (inner classes) ont accès à d'autres membres de la classe englobante, même si elles sont déclarées privé. Statique classes imbriquées n'ont pas accès à d'autres membres de la classe englobante.
...

Remarque: Une statique de la classe imbriquée interagit avec les membres de l'instance de l'extérieur de la classe (et d'autres classes), à l'instar de tout autre haut-niveau de la classe. En effet, une statique de la classe imbriquée est sur le plan comportemental d'un haut-niveau de la classe qui a été imbriqué dans un autre top-niveau de la classe pour l'emballage de commodité.

Il n'est pas nécessaire pour LinkedList.Entry à haut-niveau de la classe telle qu'elle est seulement utilisée par LinkedList (il y a quelques autres interfaces qui ont aussi statique classes imbriquées nommé Entry, comme Map.Entry - même concept). Et comme il n'a pas besoin d'avoir accès à LinkedList membres, il est logique pour qu'il soit statique - c'est beaucoup plus propre approche.

Comme Jon Skeet points, je pense que c'est une meilleure idée si vous utilisez une classe imbriquée est de commencer avec elle étant statique, et de décider ensuite si il a vraiment besoin d'être non-statique en fonction de votre utilisation.

49voto

Jon Skeet Points 692016

À mon avis, la question devrait être inversée chaque fois que vous voyez une classe interne - faut-il vraiment 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 contenant?

Rappelez-vous, je suis biaisé en tant que fan C # - C # n'a pas l'équivalent des classes internes, bien qu'il ait des types imbriqués. Je ne peux pas dire que j'ai déjà manqué des classes internes :)

31voto

Leigh Points 2144

Il y a des problèmes de rétention de mémoire non évidents à prendre en compte ici. Comme 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 conduire à des égratignures lorsque la classe externe n'est pas collectée, même s'il semble que rien ne la mentionne.

4voto

Vinze Points 1736

Exemple simple:

 package test;

public class UpperClass {
public static class StaticInnerClass {}

public class InnerClass {}

public static void main(String[] args) {
	// works
	StaticInnerClass stat = new StaticInnerClass();
	// doesn't compile
	InnerClass inner = new InnerClass();
}
}
 

Si elle n'est pas 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)

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