Warum können wir keine statische Methode in einer (nicht statischen) inneren Klasse haben?


142

Warum können wir in einer nicht statischen inneren Klasse keine statische Methode haben?

Wenn ich die innere Klasse statisch mache, funktioniert es. Warum?


4
Denn jetzt ist Java das alte COBOL :)
ses

Das Fazit lautet: Weil sie es noch nicht implementiert haben.
intrepidis

1
'Nicht statisches Inneres' ist eine Tautologie.
Marquis von Lorne

Wenn Sie Ihre innere Klasse nicht anderen zugänglich machen möchten und hoffen, dass sie statische Methoden enthält, können Sie die Modifikatoren sowohl "privat" als auch "statisch" für die innere Klasse festlegen.
Willie Z

Eine innere Klasse ist per Definition nicht statisch. Sie können eine statische verschachtelte / Member-Klasse und eine nicht statische verschachtelte / Member-Klasse haben. Letzteres ist auch als innere Klasse bekannt. (Referenz: Abschnitt 8.1.3 des JLS besagt: "Eine innere Klasse ist eine verschachtelte Klasse, die nicht explizit oder implizit deklariert ist static.")
Erwin Bolwidt

Antworten:


111

Da eine Instanz einer inneren Klasse implizit einer Instanz ihrer äußeren Klasse zugeordnet ist, kann sie selbst keine statischen Methoden definieren. Da eine statisch verschachtelte Klasse nicht direkt auf Instanzvariablen oder Methoden verweisen kann, die in ihrer umschließenden Klasse definiert sind, kann sie nur über eine Objektreferenz verwendet werden. Es ist sicher, statische Methoden in einer statisch verschachtelten Klasse zu deklarieren.


7
Ich weiß, dass eine innere Klasse mit einer Instanz ihrer äußeren Klasse verbunden ist, und ich weiß, dass es irgendwie nutzlos ist, statische Mitglieder innerhalb einer inneren Klasse zu deklarieren, aber ich frage mich immer noch, warum eine innere Klasse keine statischen Mitglieder deklarieren kann.
Kareem

15
In C ++ können Sie haben, so ist dies ein Fehler in der Java-Sprache.
Industrie-Antidepressivum

39
Das Wort Bug ... Ich glaube nicht, dass dieses Wort bedeutet, was Sie denken, dass es bedeutet.
Seth Nelson

24
Ein passenderer Ausdruck wäre "nervig als Mothertrucker". Verstehe nicht, warum Java dies nicht zulässt. Manchmal möchte ich, dass eine innere Klasse Eigenschaften der übergeordneten Klasse verwendet, aber statische Methoden für einen besseren Namespace beibehält. Stimmt etwas an sich nicht? :(
Angad

6
Genau. Ich möchte eine Utility-Innenklasse schreiben. Einige seiner Methoden würden vom Zugriff auf die äußere Klasse profitieren, daher kann ich sie nicht statisch machen, aber einige ihrer Methoden sind nur Dienstprogrammfunktionen. Warum kann ich nicht anrufen A.B.sync(X)oder sogar (aus A heraus) B.sync(x)?
Edward Falk

44

Es macht nicht viel Sinn, eine statische Methode in einer nicht statischen inneren Klasse zuzulassen. Wie würden Sie darauf zugreifen? Sie können (zumindest anfänglich) nicht auf eine nicht statische Instanz der inneren Klasse zugreifen, ohne eine Instanz der äußeren Klasse zu durchlaufen. Es gibt keine rein statische Möglichkeit, eine nicht statische innere Klasse zu erstellen.

Für eine äußere Klasse Outerkönnen Sie auf eine statische Methode test()wie die folgende zugreifen :

Outer.test();

Für eine statische innere Klasse Innerkönnen Sie wie folgt auf ihre statische Methode zugreifen innerTest():

Outer.Inner.innerTest();

Wenn dies Innerjedoch nicht statisch ist, gibt es jetzt keine rein statische Möglichkeit, auf die Methode zu verweisen innertest. Nicht statische innere Klassen sind an eine bestimmte Instanz ihrer äußeren Klasse gebunden. Eine Funktion unterscheidet sich von einer Konstanten darin, dass ein Verweis auf Outer.Inner.CONSTANTgarantiert so eindeutig ist, wie es ein Funktionsaufruf Outer.Inner.staticFunction();nicht ist. Angenommen, Sie haben Inner.staticFunction()diese Anrufe getState(), die in definiert sindOuter . Wenn Sie versuchen, diese statische Funktion aufzurufen, haben Sie jetzt einen mehrdeutigen Verweis auf die innere Klasse. Das heißt, auf welcher Instanz der inneren Klasse rufen Sie die statische Funktion auf? Es ist wichtig. Es gibt keine wirklich statische Möglichkeit, auf diese statische Methode zu verweisen, da implizit auf das äußere Objekt verwiesen wird.

Paul Bellora hat Recht, dass die Sprachdesigner dies hätten zulassen können. Sie müssten dann in statischen Methoden der nicht statischen inneren Klasse jeglichen Zugriff auf den impliziten Verweis auf die äußere Klasse sorgfältig untersagen. Welchen Wert hat es an dieser Stelle, eine innere Klasse zu sein, wenn Sie nur statisch auf die äußere Klasse verweisen können? Und wenn der statische Zugriff in Ordnung ist, warum nicht die gesamte innere Klasse als statisch deklarieren? Wenn Sie einfach die innere Klasse selbst statisch machen, haben Sie keinen impliziten Verweis auf die äußere Klasse, und Sie haben diese Mehrdeutigkeit nicht mehr.

Wenn Sie tatsächlich benötigen statische Methoden auf einer nicht-statische innere Klasse, dann müssen Sie wahrscheinlich Ihr Design zu überdenken.


6
-1 Ich muss dem Winkel, den Sie hier eingenommen haben, nicht zustimmen. Sicherlich können wir einen inneren Klasse - Typen, zum Beispiel beziehen sie Outer.Inner i = new Outer().new Inner();auch innere Klassen sind erlaubt zu statisch deklarieren Konstanten nach JLS §15.28.
Paul Bellora

2
Ja, innere Klassen können statische Konstanten deklarieren . Das hat nichts mit statischen Methoden zu tun! Obwohl Sie nicht statisch auf eine statische Methode verweisen können , wird davon abgeraten. Alle Tools zur Codequalität beschweren sich aus gutem Grund über diese Art von Referenz. Und du hast meinen Standpunkt verfehlt. Ich habe nie gesagt, dass es keine Möglichkeit gibt, auf eine statische innere Klasse zu verweisen. Ich sagte, es gibt keine STATISCHE Möglichkeit, auf die statische Methode einer inneren Klasse einer nicht statischen äußeren Klasse zu verweisen. Daher gibt es keine RICHTIGE Möglichkeit, darauf zu verweisen.
Eddie

25
"Es macht nicht viel Sinn, eine statische Methode in einer nicht statischen inneren Klasse zuzulassen. Wie würden Sie darauf zugreifen?" Sie würden anrufen, Outer.Inner.staticMethod()so wie Sie zugreifen können Outer.Inner.CONSTANT. "Sie können nicht auf ... eine nicht statische Instanz der inneren Klasse zugreifen, ohne eine Instanz der äußeren Klasse zu durchlaufen." Warum brauchen Sie eine Instanz? Sie brauchen keine Instanz von, Outerum anzurufen Outer.staticMethod(). Ich weiß, dass dies nicht pingelig ist, aber mein Punkt ist, dass es keinen Sinn macht, Ihre Antwort so zu formulieren. IMHO hätten die Sprachdesigner es zulassen können, wenn sie wollten.
Paul Bellora

1
Der Unterschied zwischen Outer.Inner.CONSTANTund Outer.Inner.staticMethod()besteht darin, dass eine Referenz auf eine Konstante keine Chance hat, implizit auf die Instanz zu verweisen, Outerin der sie Innerinstanziiert wurde. Alle Referenzen haben Outer.staticMethod()denselben exakten Status. Alle Referenzen haben Outer.Inner.CONSTANTdenselben exakten Status. Verweise auf Outer.Inner.staticMethod()sind jedoch nicht eindeutig: Der "statische" Zustand ist aufgrund des impliziten Verweises auf die äußere Klasse in jeder Instanz von nicht wirklich statisch Inner. Es gibt keine wirklich eindeutige, statische Möglichkeit, darauf zuzugreifen.
Eddie

3
@Eddie Sie können in einer statischen Methode nicht auf Instanzfelder verweisen, daher besteht kein Konflikt in Bezug auf die Unfähigkeit, auf das implizite Instanzfeld zu verweisen Outer.this. Ich stimme den Java-Sprachdesignern zu, dass es keinen Grund gibt, statische Methoden oder nicht endgültige statische Felder in inneren Klassen zuzulassen, da sich alles in einer inneren Klasse im Kontext der einschließenden Klasse befinden sollte.
Theodore Murdock

20

Ich habe eine Theorie, die richtig sein kann oder nicht.

Zunächst sollten Sie einige Dinge darüber wissen, wie innere Klassen in Java implementiert werden. Angenommen, Sie haben diese Klasse:

class Outer {
    private int foo = 0;
    class Inner implements Runnable {
        public void run(){ foo++; }
    }
    public Runnable newFooIncrementer(){ return new Inner(); }
}

Wenn Sie es kompilieren, sieht der generierte Bytecode so aus, als hätten Sie Folgendes geschrieben:

class Outer {
    private int foo = 0;
    static class Inner implements Runnable {
        private final Outer this$0;
        public Inner(Outer outer){
            this$0 = outer;
        }
        public void run(){ this$0.foo++; }
    }
    public Runnable newFooIncrementer(){ return new Inner(this); }
}

Wenn wir nun statische Methoden in nicht statischen inneren Klassen zulassen, möchten Sie möglicherweise so etwas tun.

class Outer {
    private int foo = 0;
    class Inner {
        public static void incrFoo(){ foo++; }
    }
}

... was ziemlich vernünftig aussieht, da die InnerKlasse eine Inkarnation pro OuterInstanz zu haben scheint . Aber wie wir oben gesehen haben, sind die nicht statischen inneren Klassen wirklich nur syntaktischer Zucker für statische "innere" Klassen, so dass das letzte Beispiel ungefähr gleichbedeutend wäre mit:

class Outer {
    private int foo = 0;
    static class Inner {
        private final Outer this$0;
        public Inner(Outer outer){
            this$0 = outer;
        }
        public static void incrFoo(){ this$0.foo++; }
    }
}

... was eindeutig nicht funktioniert, da this$0es nicht statisch ist. Auf diese Weise wird erklärt, warum statische Methoden nicht zulässig sind (obwohl Sie argumentieren könnten, dass Sie statische Methoden zulassen könnten, solange sie nicht auf das umschließende Objekt verweisen) und warum Sie keine nicht endgültigen statischen Felder haben können ( Es wäre kontraintuitiv, wenn Instanzen nicht statischer innerer Klassen von verschiedenen Objekten den "statischen Zustand" teilen würden. Es erklärt auch , warum letzte Felder sind erlaubt (solange sie das einschließende Objekt nicht verweisen).


7
Dies ist jedoch nur ein normaler Fehler vom Typ "Versuch, aus einem statischen Kontext auf eine nicht statische Variable zuzugreifen" - nicht anders, als wenn eine statische Methode der obersten Ebene versucht, auf die Instanzvariable ihrer eigenen Klasse zuzugreifen.
Lawrence Dol

2
Ich mag diese Antwort, weil sie tatsächlich erklärt, warum sie technisch nicht möglich ist, obwohl sie syntaktisch möglich erscheinen könnte.
LoPoBo

@gustafc, ich denke das war eine ausgezeichnete Erklärung. Aber wie Lawrence betont, ist es nur ein Fehler aufgrund des Verweises auf foo, der nicht statisch ist. Aber was ist, wenn ich public static double sinDeg(double theta) { ... }eine innere Mathe-Dienstprogrammklasse schreiben wollte ?
Edward Falk

6

Der einzige Grund ist "kein Muss". Warum also die Mühe machen, es zu unterstützen?

Syntaktisch gibt es keinen Grund, einer inneren Klasse zu verbieten, statische Mitglieder zu haben. Obwohl eine Instanz von Innereiner Instanz von zugeordnet ist Outer, ist es dennoch möglich, Outer.Inner.myStaticein statisches Mitglied von zu referenzieren, Innerwenn Java dies beschließt.

Wenn Sie etwas für alle Instanzen von Innerfreigeben müssen, können Sie es einfach Outerals statische Elemente einfügen. Dies ist nicht schlimmer, als wenn Sie statische Mitglieder verwenden, in Innerdenen Sie Outerweiterhin auf jedes private Mitglied von zugreifen könnenInner ohnehin zugegriffen werden kann (verbessert die Kapselung nicht).

Wenn Sie etwas für alle Innervon einem outerObjekt erstellten Instanzen freigeben müssen, ist es sinnvoller, sie zu platzierenOuter als normale Mitglieder Klasse einzuteilen.

Ich stimme der Meinung nicht zu, dass "eine statisch verschachtelte Klasse so ziemlich nur eine Klasse der obersten Ebene ist". Ich denke, es ist besser, eine statisch verschachtelte Klasse / innere Klasse wirklich als Teil der äußeren Klasse zu betrachten, da sie auf die privaten Mitglieder der äußeren Klasse zugreifen können. Und Mitglieder der äußeren Klasse sind auch "Mitglieder der inneren Klasse". Es ist also nicht erforderlich, statische Elemente in der inneren Klasse zu unterstützen. Ein gewöhnliches / statisches Mitglied in der äußeren Klasse wird ausreichen.


Innere Klassen sind auch kein "Muss". Da die Sprache jedoch innere Klassen bereitstellt, sollte sie eine vollständige und aussagekräftige Implementierung dieser Klassen bieten.
intrepidis

4

Von: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

Wie bei Instanzmethoden und -variablen ist eine innere Klasse einer Instanz ihrer einschließenden Klasse zugeordnet und hat direkten Zugriff auf die Methoden und Felder dieses Objekts. Da eine innere Klasse einer Instanz zugeordnet ist, kann sie auch keine statischen Elemente selbst definieren.

Die Erklärung von Oracle ist oberflächlich und handgewellt. Da es keinen technischen oder syntaktischen Grund gibt, statische Mitglieder innerhalb einer inneren Klasse zu verhindern (dies ist in anderen Sprachen wie C # zulässig), war die Motivation der Java-Designer wahrscheinlich konzeptioneller Geschmack und / oder eine Frage der technischen Bequemlichkeit.

Hier ist meine Spekulation:

Im Gegensatz zu Klassen der obersten Ebene sind innere Klassen instanzabhängig: Eine Instanz der inneren Klasse ist einer Instanz jeder ihrer äußeren Klassen zugeordnet und hat direkten Zugriff auf ihre Mitglieder. Dies ist die Hauptmotivation, sie in Java zu haben. Anders ausgedrückt: Eine innere Klasse ist zur Instanziierung im Kontext einer äußeren Klasseninstanz gedacht . Ohne eine Instanz der äußeren Klasse sollte eine innere Klasse nicht besser verwendbar sein als die anderen Instanzmitglieder der äußeren Klasse. Nennen wir dies den instanzabhängigen Geist der inneren Klassen.

Die Natur der statischen Elemente (die NICHT objektorientiert sind) kollidiert mit der instanzabhängigen Geist innerer Klassen (die objektorientiert sind), da Sie ein statisches Element einer inneren Klasse ohne eine Instanz einer äußeren Klasse durch referenzieren / aufrufen können unter Verwendung des qualifizierten inneren Klassennamens.

Insbesondere statische Variablen können auf noch eine andere Weise beleidigen: Zwei Instanzen einer inneren Klasse, die verschiedenen Instanzen der äußeren Klasse zugeordnet sind, würden statische Variablen gemeinsam nutzen. Da Variablen eine Komponente des Status sind, teilen sich die beiden Instanzen der inneren Klasse praktisch den Status unabhängig von den Instanzen der äußeren Klasse, denen sie zugeordnet sind. Es ist nicht inakzeptabel, dass statische Variablen auf diese Weise funktionieren (wir akzeptieren sie in Java als sinnvollen Kompromiss für die OOP-Reinheit), aber es gibt wohl ein tieferes Vergehen, wenn sie in inneren Klassen zugelassen werden, deren Instanzen bereits mit Instanzen der äußeren Klasse gekoppelt sind von Entwurf. Das Verbot statischer Mitglieder innerhalb der inneren Klassen zugunsten des instanzabhängigen Geistes erntet den zusätzlichen Vorteil, diese tiefere OOP-Straftat zu verhindern.

Andererseits ist eine solche Straftat nicht mit statischen Konstanten verbunden, die keinen sinnvollen Zustand darstellen und daher zulässig sind. Warum nicht statische Konstanten verbieten, um maximale Übereinstimmung mit dem instanzabhängigen Geist zu erzielen ? Vielleicht, weil Konstanten nicht mehr Speicher als nötig beanspruchen müssen (wenn sie nicht statisch sein müssen, werden sie in jede Instanz der inneren Klasse kopiert, was möglicherweise verschwenderisch ist). Ansonsten kann ich mir den Grund für die Ausnahme nicht vorstellen.

Es mag keine solide Argumentation sein, aber IMO macht es den größten Sinn aus der flüchtigen Bemerkung von Oracle in dieser Angelegenheit.


3

Kurze Antwort: Das mentale Modell, das die meisten Programmierer für die Funktionsweise von Scope haben, ist nicht das von Javac verwendete Modell. Die Anpassung an das intuitivere Modell hätte eine große Änderung der Funktionsweise von Javac erforderlich gemacht.

Der Hauptgrund, warum statische Elemente in inneren Klassen wünschenswert sind, ist die Sauberkeit des Codes - ein statisches Element, das nur von einer inneren Klasse verwendet wird, sollte darin leben, anstatt in der äußeren Klasse platziert zu werden. Erwägen:

class Outer {
   int outID;

   class Inner {
      static int nextID;
      int id = nextID++;

      String getID() {
         return outID + ":" + id;
      }
   }
}

Überlegen Sie, was in getID () vor sich geht, wenn ich den nicht qualifizierten Bezeichner "outID" verwende. Der Bereich, in dem diese Kennung angezeigt wird, sieht ungefähr so ​​aus:

Outer -> Inner -> getID()

Auch hier umfasst die "Outer" -Ebene des Bereichs sowohl statische als auch Instanzmitglieder von Outer, da dies genau die Funktionsweise von Javac ist. Dies ist verwirrend, da wir normalerweise aufgefordert werden, den statischen Teil einer Klasse als eine weitere Ebene des Geltungsbereichs zu betrachten:

Outer static -> Outer instance -> instanceMethod()
         \----> staticMethod()

Auf diese Weise kann staticMethod () natürlich nur statische Mitglieder von Outer sehen. Wenn javac jedoch so funktioniert, würde das Verweisen auf eine Instanzvariable in einer statischen Methode zu dem Fehler "Name kann nicht behoben werden" führen. Was wirklich passiert, ist, dass der Name im Gültigkeitsbereich gefunden wird, aber dann eine zusätzliche Überprüfungsebene aktiviert wird und herausfindet, dass der Name in einem Instanzkontext deklariert wurde und aus einem statischen Kontext referenziert wird.

OK, wie hängt das mit inneren Klassen zusammen? Naiv denken wir, dass es keinen Grund gibt, warum innere Klassen keinen statischen Bereich haben können, weil wir uns den Bereich so vorstellen:

Outer static -> Outer instance -> Inner instance -> getID()
         \------ Inner static ------^

Mit anderen Worten, statische Deklarationen in der inneren Klasse und Instanzdeklarationen in der äußeren Klasse sind beide im Instanzkontext der inneren Klasse gültig, aber keine dieser Deklarationen ist tatsächlich in der anderen verschachtelt. beide sind stattdessen im statischen Bereich von Outer verschachtelt.

So funktioniert javac einfach nicht - es gibt eine einzige Ebene für den Bereich sowohl für statische als auch für Instanzmitglieder, und der Bereich ist immer streng verschachtelt. Sogar die Vererbung wird implementiert, indem Deklarationen in die Unterklasse kopiert werden, anstatt den Bereich der Oberklasse zu verzweigen und zu durchsuchen.

Um statische Mitglieder innerer Klassen zu unterstützen, müsste javac entweder statische Bereiche und Instanzbereiche aufteilen und Verzweigungs- und Wiederverbindungsbereichshierarchien unterstützen, oder es müsste seine einfache boolesche Idee des "statischen Kontexts" erweitern, um den Kontexttyp auf allen Ebenen zu verfolgen der verschachtelten Klasse im aktuellen Bereich.


Ich denke, eine grundlegendere Schwierigkeit, nicht statischen inneren Klassen nicht konstante statische Elemente zuzuweisen, besteht darin, dass Programmierer, die solche Elemente deklarieren, möglicherweise beabsichtigen, sie an Instanzen der äußeren Klasse zu binden oder sie wirklich statisch zu machen. In Fällen, in denen ein Konstrukt - wenn es legal ist - sinnvoll als eine von zwei verschiedenen Dingen bezeichnet werden kann und in denen beide Dinge auf andere eindeutige Weise ausgedrückt werden können, ist es oft besser, dieses Konstrukt als illegal anzugeben, als es als anzugeben entweder eine Bedeutung haben.
Supercat

3

Warum können wir in einer nicht statischen inneren Klasse keine statische Methode haben?

Hinweis: Eine nicht statisch verschachtelte Klasse wird als innere Klasse bezeichnet, sodass Sie sie nicht non-static inner classals solche haben.

Eine innere Klasseninstanz existiert nicht ohne eine entsprechende Instanz der äußeren Klasse. Eine innere Klasse kann keine anderen statischen Elemente als Kompilierungszeitkonstanten deklarieren. Wenn es erlaubt wäre, hätte es Unklarheiten über die Bedeutung von gegeben static. In diesem Fall hätte es gewisse Verwirrungen gegeben:

  1. Bedeutet dies, dass es in VM nur eine Instanz gibt?
  2. Oder nur eine Instanz pro äußerem Objekt?

Aus diesem Grund haben die Designer wahrscheinlich beschlossen, dieses Problem überhaupt nicht zu behandeln.

Wenn ich die innere Klasse statisch mache, funktioniert es. Warum ?

Auch hier können Sie eine innere Klasse nicht statisch machen, sondern eine statische Klasse als verschachtelt deklarieren. In diesem Fall ist diese verschachtelte Klasse tatsächlich Teil der äußeren Klasse und kann ohne Probleme statische Elemente haben.


3

Dieses Thema hat bei vielen Aufmerksamkeit erregt, dennoch werde ich versuchen, es auf einfachste Weise zu erklären.

Zunächst wird unter Bezugnahme auf http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1 eine Klasse oder Schnittstelle unmittelbar vor dem ersten Auftreten / Aufruf initialisiert eines Mitglieds, dem das statische Schlüsselwort vorangestellt ist.

  1. Wenn wir uns also mit einem statischen Element innerhalb einer inneren Klasse abfinden, führt dies zur Initialisierung der inneren Klasse, nicht unbedingt der äußeren / umschließenden Klasse. Wir behindern also die Klasseninitialisierungssequenz.

  2. Berücksichtigen Sie auch die Tatsache, dass eine nicht statische innere Klasse der Instanz einer einschließenden / äußeren Klasse zugeordnet ist. Die Zuordnung zu einer Instanz bedeutet also, dass die innere Klasse innerhalb einer Instanz der äußeren Klasse vorhanden ist und sich zwischen den Instanzen unterscheidet.

Um den Punkt zu vereinfachen, benötigen wir für den Zugriff auf das statische Element eine Instanz einer äußeren Klasse, aus der wir erneut eine Instanz einer nicht statischen inneren Klasse erstellen müssen. Statische Mitglieder sollten nicht an Instanzen gebunden sein, daher erhalten Sie einen Kompilierungsfehler.


2

Eine innere Klasse unterscheidet sich grundlegend von einer statisch verschachtelten Klasse, obwohl beide in der Syntax ähnlich sind. Statisch verschachtelte Klassen sind nur ein Mittel zur Gruppierung, während innere Klassen eine starke Assoziation - und Zugriff auf alle Werte - ihrer äußeren Klasse haben. Sie sollten sicher sein, warum Sie eine innere Klasse verwenden möchten, und dann sollte es ziemlich natürlich sein, welche Sie verwenden müssen. Wenn Sie eine statische Methode deklarieren müssen, handelt es sich wahrscheinlich um eine statisch verschachtelte Klasse, die Sie sowieso möchten.


Benedikt, was meinst du mit "statisch verschachtelte Klassen sind nur ein Mittel zur Gruppierung"?
Ankur

0

Angenommen, es gibt zwei Instanzen der äußeren Klasse und beide haben die innere Klasse instanziiert. Wenn die innere Klasse nun ein statisches Element hat, wird nur eine Kopie dieses Elements im Heap-Bereich gespeichert. In diesem Fall verweisen beide Objekte der äußeren Klasse darauf Einzelkopie & sie können es zusammen ändern. Dies kann zu einer "Dirty Read" -Situation führen, um zu verhindern, dass Java diese Einschränkung angewendet hat. Eine weitere Stärke, die dieses Argument unterstützt, ist, dass Java hier endgültige statische Mitglieder zulässt, deren Werte nicht sein können geändert von einem der äußeren Klassenobjekte. Bitte lassen Sie mich, wenn ich falsch liege.


0

Zunächst einmal, warum jemand das statische Element in einer nicht statischen inneren Klasse definieren möchte? Die Antwort lautet, damit das äußere Klassenmitglied diese statischen Elemente nur mit dem inneren Klassennamen verwenden kann. Richtig?

In diesem Fall können wir das Mitglied in der äußeren Klasse direkt definieren. Dies wird allen Objekten der inneren Klasse innerhalb der äußeren Klasseninstanz zugeordnet.

wie unten Code,

public class Outer {

  class Inner {

    public static void method() {

    }

  }

}

kann so geschrieben werden

public class Outer {

  void method() {

   }

   class Inner {


  }

}

Meiner Meinung nach lässt der Java-Designer diese Funktionalität nicht zu, um den Code nicht zu komplizieren. Andernfalls wird diese Funktionalität möglicherweise in zukünftigen Versionen mit einigen weiteren Funktionen angezeigt.


0

Versuchen Sie, die Klasse als normales Feld zu behandeln, dann werden Sie verstehen.

//something must be static. Suppose something is an inner class, then it has static keyword which means it's a static class
Outer.something 

-1

Es ist sinnlos, Mitglieder der inneren Klasse als statisch zu haben, da Sie überhaupt nicht darauf zugreifen können.

Denken Sie darüber nach, um auf ein statisches Mitglied zuzugreifen, verwenden Sie className.memberName. In unserem Fall sollte es so etwas wie OuterclassName.innerclassName.memberName sein. Jetzt sehen Sie, warum Innerclass statisch sein muss.


-2

Sie dürfen statische Methoden für statisch verschachtelte Klassen verwenden. Beispielsweise

public class Outer {

  public static class Inner {

    public static void method() {

    }
  }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.