class OuterClass {
class InnerClass {
static int i = 100; // compile error
static void f() { } // compile error
}
}
Bien qu'il ne soit pas possible d'accéder au champ statique avec OuterClass.InnerClass.i
, si je veux enregistrer quelque chose qui devrait être statique, par exemple le nombre d'objets InnerClass créés, il serait utile de rendre ce champ statique. Alors pourquoi Java interdit-il les champs / méthodes statiques dans les classes internes?
EDIT: Je sais comment rendre le compilateur heureux avec une classe imbriquée statique (ou une classe interne statique), mais ce que je veux savoir, c'est pourquoi java interdit les champs / méthodes statiques à l'intérieur des classes internes (ou classe interne ordinaire) à la fois de la conception du langage et aspects de mise en œuvre, si quelqu'un en sait plus à ce sujet.
java
inner-classes
static-members
Jichao
la source
la source
Réponses:
L'idée derrière les classes internes est d'opérer dans le contexte de l'instance englobante. D'une manière ou d'une autre, autoriser des variables et des méthodes statiques contredit cette motivation?
la source
Parce que ces classes internes sont des classes internes "d'instance". Autrement dit, ils sont comme un attribut d'instance de l'objet englobant.
Puisqu'il s'agit de classes "d'instance", cela n'a aucun sens d'autoriser les
static
fonctionnalités, car celastatic
est censé fonctionner sans instance en premier lieu.C'est comme si vous essayiez de créer un attribut statique / instance en même temps.
Prenons l'exemple suivant:
class Employee { public String name; }
Si vous créez deux instances d'employé:
Employee a = new Employee(); a.name = "Oscar"; Employee b = new Employee(); b.name = "jcyang";
Il est clair pourquoi chacun a sa propre valeur pour la propriété
name
, non?La même chose se produit avec la classe interne; chaque instance de classe interne est indépendante de l'autre instance de classe interne.
Donc, si vous essayez de créer un
counter
attribut de classe, il n'y a aucun moyen de partager cette valeur entre deux instances différentes.class Employee { public String name; class InnerData { static count; // ??? count of which ? a or b? } }
Lorsque vous créez l'instance
a
etb
dans l'exemple ci-dessus, quelle serait une valeur correcte pour la variable statiquecount
? Il n'est pas possible de le déterminer, car l'existence duInnerData
classe dépend entièrement de chacun des objets englobants.C'est pourquoi, lorsque la classe est déclarée comme
static
, elle n'a plus besoin d'une instance vivante pour se vivre. Maintenant qu'il n'y a pas de dépendance, vous pouvez déclarer librement un attribut statique.Je pense que cela semble répétitif, mais si vous pensez aux différences entre les attributs d'instance et de classe, cela aura du sens.
la source
final
, les champs statiques sont autorisés dans la classe interne de java. Comment expliquez-vous ce scénario?InnerClass
ne peut pas avoir destatic
membres car il appartient à une instance (deOuterClass
). Si vous déclarezInnerClass
lestatic
détacher de l'instance, votre code se compilera.class OuterClass { static class InnerClass { static int i = 100; // no compile error static void f() { } // no compile error } }
BTW: Vous pourrez toujours créer des instances de
InnerClass
.static
dans ce contexte, permet que cela se produise sans une instance englobante deOuterClass
.la source
InnerClass
n'appartient pas àOuterClass
, les instances en font. Les deux classes elles-mêmes n'ont pas une telle relation. La question de savoir pourquoi vous ne pouvez pas avoir de méthodes statiques estInnerClass
toujours d'actualité.En fait, vous pouvez déclarer des champs statiques s'ils sont des constantes et sont écrits au moment de la compilation.
class OuterClass { void foo() { class Inner{ static final int a = 5; // fine static final String s = "hello"; // fine static final Object o = new Object(); // compile error, because cannot be written during compilation } } }
la source
Comme les classes internes dépendent de l'instance de la classe englobante / externe, la classe externe doit être initialisée avant l'initialisation de la classe interne.
C'est JLS dit à propos de l'initialisation de classe. Le point dont nous avons besoin est que la classe T sera initialisée si
Donc, si la classe interne a un accès à un champ statique, cela entraînera l'initialisation de la classe interne, mais cela ne garantira pas que la classe englobante est initialisée.
Cela violerait certaines règles de base . vous pouvez passer à la dernière section (à
two cases
) pour éviter les trucs noobUne chose à propos , quand certains sont
static nested
class
nested class
static
elle se comportera comme une classe normale à tous égards et elle est associée à la classe Outer.Mais le concept de
Inner class
/ est-il sera associé à la classe externe / englobante. Veuillez noter associé à l' instance et non à la classe. L'association à une instance signifie clairement que (d' après le concept de variable d'instance ), elle existera à l'intérieur d'une instance et sera différente d'une instance à l'autre.non-static
nested class
instance
Maintenant, lorsque nous créons quelque chose de statique, nous nous attendons à ce qu'il soit initialisé lorsque la classe est en cours de chargement et devrait être partagé entre toutes les instances. Mais pour être non statiques, même les classes internes elles-mêmes ( vous pouvez certainement oublier l'instance de la classe interne pour le moment ) ne sont pas partagées avec toutes les instances de la classe externe / englobante ( du moins conceptuellement ), alors comment pouvons-nous nous attendre à ce qu'une variable de la classe interne sera partagée entre toutes les instances de la classe interne.
Donc, si Java nous permet d'utiliser une variable statique dans une classe imbriquée non statique. il y aura deux cas .
context of instance
(variable d'instance). C'est un NON alors.la source
Voici la motivation que je trouve la mieux adaptée à cette "limite": Vous pouvez implémenter le comportement d'un champ statique d'une classe interne comme un champ d'instance de l'objet externe; Vous n'avez donc pas besoin de champs / méthodes statiques . Le comportement que je veux dire est que toutes les instances de classe interne d'un objet partagent un champ (ou une méthode).
Donc, supposons que vous vouliez compter toutes les instances de classe interne, vous feriez:
public class Outer{ int nofInner; //this will count the inner class //instances of this (Outer)object //(you know, they "belong" to an object) static int totalNofInner; //this will count all //inner class instances of all Outer objects class Inner { public Inner(){ nofInner++; totalNofInner++; } } }
la source
final
alors?En termes simples, les classes internes non statiques sont des variables d'instance pour la classe externe et elles ne sont créées que lorsqu'une classe externe est créée et qu'un objet de classe externe est créé au moment de l'exécution, tandis que les variables statiques sont créées au moment du chargement de la classe. Donc, la classe interne non statique est une chose à l'exécution, c'est pourquoi static n'est pas la partie d'une classe interne non statique.
REMARQUE: traitez toujours les classes internes comme une variable pour une classe externe, elles peuvent être statiques ou non statiques comme toutes les autres variables.
la source
static final
constantes.Parce que cela créerait une ambiguïté dans le sens de «statique».
Tiré de "Core Java SE 9 for the Impatient" par Cay S. Horstmann. Pg 90 Chapitre 2.6.3
la source
Je suppose que c'est pour la cohérence. Bien qu'il ne semble pas y avoir de limitation technique, vous ne pourrez pas accéder aux membres statiques de la classe interne de l'extérieur, c'est
OuterClass.InnerClass.i
-à- dire parce que l'étape du milieu n'est pas statique.la source
static final
constantes.