Dlaczego nie możemy mieć metody statycznej w (niestatycznej) klasie wewnętrznej?

142

Dlaczego nie możemy mieć metody statycznej w niestatycznej klasie wewnętrznej?

Jeśli uczynię wewnętrzną klasę statyczną, to działa. Czemu?

Rahul Garg
źródło
4
Ponieważ teraz Java to stary COBOL :)
sesja
Najważniejsze jest to, że jeszcze go nie zaimplementowali.
intrepidis
1
„Niestatyczna wewnętrzna” to tautologia.
Markiz Lorne
Jeśli nie chcesz ujawniać swojej wewnętrznej klasy innym osobom i masz nadzieję, że zawiera ona metody statyczne, możesz umieścić modyfikatory zarówno „private”, jak i „static” w klasie wewnętrznej.
Willie Z
Klasa wewnętrzna z definicji nie jest statyczna. Możesz mieć statyczną klasę zagnieżdżoną / składową i niestatyczną klasę zagnieżdżoną / składową. Ta ostatnia jest również znana jako klasa wewnętrzna. (Odniesienie: sekcja 8.1.3 JLS stwierdza: „ Klasa wewnętrzna jest klasą zagnieżdżoną, która nie została zadeklarowana jawnie ani niejawnie static”)
Erwin Bolwidt,

Odpowiedzi:

111

Ponieważ wystąpienie klasy wewnętrznej jest niejawnie skojarzone z wystąpieniem swojej klasy zewnętrznej, nie może ono samodzielnie definiować żadnych metod statycznych. Ponieważ statyczna klasa zagnieżdżona nie może odwoływać się bezpośrednio do zmiennych instancji ani metod zdefiniowanych w otaczającej jej klasie, może ich używać tylko poprzez odwołanie do obiektu, dlatego można bezpiecznie zadeklarować metody statyczne w statycznej klasie zagnieżdżonej.

Bill the Lizard
źródło
7
Wiem, że klasa wewnętrzna jest powiązana z wystąpieniem jej klasy zewnętrznej i wiem, że to trochę bezużyteczne, że możemy deklarować statyczne elementy w klasie wewnętrznej, ale wciąż pytam, dlaczego klasa wewnętrzna nie może deklarować elementów statycznych?
Kareem
15
W C ++ możesz to mieć, więc jest to błąd w języku Java.
Środek przeciwdepresyjny przemysłowy
39
Słowo błąd ... Nie sądzę, że to słowo oznacza to, co myślisz, że oznacza.
Seth Nelson
24
Bardziej odpowiednim zwrotem byłoby „irytujące jak mothertrucker”. Nie rozumiem, dlaczego Java na to nie pozwala. Czasami chcę, aby klasa wewnętrzna korzystała z właściwości klasy nadrzędnej, ale zachowaj metody statyczne, aby zapewnić lepszą przestrzeń nazw. Czy jest w tym coś z natury nie tak? :(
Angad
6
Dokładnie. Chcę napisać klasę użytkową. Niektóre z jego metod skorzystałyby na dostępie do klasy zewnętrznej, więc nie mogę uczynić jej statyczną, ale niektóre z jej metod są tylko funkcjami użytkowymi. Dlaczego nie mogę zadzwonić A.B.sync(X)ani nawet (z poziomu A) B.sync(x)?
Edward Falk
44

Nie ma sensu zezwalanie na statyczną metodę w niestatycznej klasie wewnętrznej; jak możesz uzyskać do niego dostęp? Nie można uzyskać dostępu (przynajmniej początkowo) do niestatycznej instancji klasy wewnętrznej bez przechodzenia przez instancję klasy zewnętrznej. Nie ma czysto statycznego sposobu tworzenia niestatycznej klasy wewnętrznej.

W przypadku klasy zewnętrznej Outermożesz uzyskać dostęp do metody statycznej w następujący sposób test():

Outer.test();

W przypadku statycznej klasy wewnętrznej Innermożna uzyskać dostęp do jej metody statycznej w następujący sposób innerTest():

Outer.Inner.innerTest();

Jeśli jednak Innernie jest statyczny, nie ma teraz czysto statycznego sposobu odniesienia się do metody innertest. Niestatyczne klasy wewnętrzne są powiązane z konkretnym wystąpieniem ich klasy zewnętrznej. Funkcja różni się od stałej tym, że odniesienie do Outer.Inner.CONSTANTjest gwarantowane jako jednoznaczne w sposób, w jaki Outer.Inner.staticFunction();nie jest to wywołanie funkcji . Powiedzmy, że masz Inner.staticFunction()wywołania getState(), które są zdefiniowane w Outer. Jeśli spróbujesz wywołać tę funkcję statyczną, masz teraz niejednoznaczne odwołanie do klasy Inner. To znaczy, na którym wystąpieniu klasy wewnętrznej wywołujesz funkcję statyczną? To ma znaczenie. Widzisz, nie ma prawdziwie statycznego sposobu odwoływania się do tej metody statycznej ze względu na niejawne odwołanie do obiektu zewnętrznego.

Paul Bellora ma rację, że projektanci języka mogli na to pozwolić. Musieliby wtedy ostrożnie zabronić dostępu do niejawnego odwołania do klasy zewnętrznej w statycznych metodach niestatycznej klasy wewnętrznej. W tym momencie, jaka jest wartość tego, że jest to klasa wewnętrzna, jeśli nie można odwoływać się do klasy zewnętrznej, chyba że statycznie? A jeśli dostęp statyczny jest w porządku, dlaczego nie zadeklarować statycznej całej klasy wewnętrznej? Jeśli po prostu uczynisz samą klasę wewnętrzną statyczną, nie masz niejawnego odniesienia do klasy zewnętrznej i nie masz już tej niejednoznaczności.

Jeśli faktycznie potrzebujesz statycznych metod na niestatycznej klasie wewnętrznej, prawdopodobnie musisz przemyśleć swój projekt.

Eddie
źródło
6
-1 Muszę się nie zgodzić z punktem widzenia, jaki tu przyjęliście. Z pewnością możemy odnieść wewnętrzny typ klasy, na przykład Outer.Inner i = new Outer().new Inner();Ponadto, klasy wewnętrzne dozwolone zadeklarować statycznych stałych według JLS §15.28.
Paul Bellora,
2
Tak, klasy wewnętrzne mogą deklarować stałe statyczne . To nie ma nic wspólnego z metodami statycznymi! Podczas może odnosić się do metody statycznej nie statycznie, to nie jest zalecane. Wszystkie narzędzia jakości kodu narzekają na tego rodzaju odniesienia i nie bez powodu. I przegapiłeś mój punkt widzenia. Nigdy nie powiedziałem, że nie ma możliwości odniesienia się do statycznej klasy wewnętrznej. Powiedziałem, że nie ma STATYCZNEGO sposobu odniesienia się do statycznej metody klasy wewnętrznej niestatycznej klasy zewnętrznej. Dlatego nie ma PRAWIDŁOWEGO sposobu na odniesienie się do niego.
Eddie,
25
„Nie ma sensu zezwalać na statyczną metodę w niestatycznej klasie wewnętrznej; jak można uzyskać do niej dostęp?” Zadzwoniłbyś Outer.Inner.staticMethod()tak, jak masz dostęp Outer.Inner.CONSTANT. „Nie można uzyskać dostępu do ... niestatycznej instancji klasy wewnętrznej bez przechodzenia przez instancję klasy zewnętrznej”. Dlaczego potrzebujesz instancji? Nie potrzebujesz instancji, Outeraby zadzwonić Outer.staticMethod(). Wiem, że jest to trudne, ale chodzi mi o to, że formułowanie odpowiedzi w ten sposób nie ma sensu. IMHO projektanci języka mogliby na to pozwolić, gdyby chcieli.
Paul Bellora,
1
Różnica między Outer.Inner.CONSTANTi Outer.Inner.staticMethod()polega na tym, że odwołanie do stałej nie ma szans na niejawne odwołanie się do wystąpienia, Outerw którym utworzono Innerwystąpienie. Wszystkie odniesienia Outer.staticMethod()mają ten sam dokładny stan. Wszystkie odniesienia Outer.Inner.CONSTANTmają ten sam dokładny stan. Jednak odwołania do Outer.Inner.staticMethod()są niejednoznaczne: stan „statyczny” nie jest w rzeczywistości statyczny, ze względu na niejawne odwołanie do klasy zewnętrznej w każdym wystąpieniu Inner. Nie ma naprawdę jednoznacznego, statycznego sposobu dostępu do niego.
Eddie,
3
@Eddie Nie możesz odwoływać się do pól instancji w metodzie statycznej, więc nie ma konfliktu związanego z niemożnością odwołania się do niejawnego pola instancji Outer.this. Zgadzam się z projektantami języka Java, że ​​nie ma powodu, aby zezwalać na statyczne metody lub nie ostateczne pola statyczne w klasach wewnętrznych, ponieważ wszystko w klasie wewnętrznej powinno znajdować się w kontekście klasy obejmującej.
Theodore Murdock
20

Mam teorię, która może być poprawna lub nie.

Po pierwsze, powinieneś wiedzieć kilka rzeczy o tym, jak klasy wewnętrzne są implementowane w Javie. Załóżmy, że masz tę klasę:

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

Kiedy go kompilujesz, wygenerowany kod bajtowy będzie wyglądał tak, jakbyś napisał coś takiego:

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); }
}

Teraz, gdybyśmy zezwolili na statyczne metody w niestatycznych klasach wewnętrznych, możesz chcieć zrobić coś takiego.

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

... co wygląda dość rozsądnie, ponieważ Innerklasa wydaje się mieć jedną inkarnację na Outerinstancję. Ale jak widzieliśmy powyżej, niestatyczne klasy wewnętrzne w rzeczywistości są po prostu cukrem syntaktycznym dla statycznych klas „wewnętrznych”, więc ostatni przykład byłby w przybliżeniu równoważny z:

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++; }
    }
}

... co najwyraźniej nie zadziała, ponieważ this$0nie jest statyczne. Ten rodzaj wyjaśnia, dlaczego metody statyczne nie są dozwolone (chociaż można argumentować, że można zezwolić na metody statyczne, o ile nie odwołują się do otaczającego obiektu) i dlaczego nie można mieć nieostatecznych pól statycznych ( byłoby sprzeczne z intuicją, gdyby instancje niestatycznych klas wewnętrznych z różnych obiektów miały wspólny „stan statyczny”). Wyjaśnia również, dlaczego końcowe pola dozwolone (o ile nie odwołują się do otaczającego obiektu).

gustafc
źródło
7
Ale to tylko zwykły błąd typu „próba uzyskania dostępu do zmiennej niestatycznej z kontekstu statycznego” - nie różni się od sytuacji, gdy metoda statyczna najwyższego poziomu próbuje uzyskać dostęp do zmiennej instancji własnej klasy.
Lawrence Dol
2
Podoba mi się ta odpowiedź, ponieważ tak naprawdę wyjaśnia, dlaczego nie jest to technicznie możliwe, mimo że składniowo mogłoby się to wydawać możliwe.
LoPoBo
@gustafc, myślę, że to było doskonałe wyjaśnienie. Ale jak wskazuje Lawrence, jest to błąd tylko z powodu odniesienia do foo, które nie jest statyczne. Ale co, gdybym chciał napisać public static double sinDeg(double theta) { ... }wewnętrzne zajęcia z narzędzi matematycznych?
Edward Falk
6

Jedynym powodem jest to, że „nie trzeba”, więc po co go wspierać?

Składniowo nie ma powodu, aby zabraniać klasie wewnętrznej posiadania statycznych elementów członkowskich. Chociaż wystąpienie programu Innerjest skojarzone z wystąpieniem programu Outer, nadal można użyć polecenia Outer.Inner.myStaticdo statycznego elementu członkowskiego, Innerjeśli zdecyduje się na to java.

Jeśli chcesz udostępnić coś we wszystkich instancjach Inner, możesz po prostu umieścić je Outerjako statyczne elementy członkowskie. Nie jest to gorsze niż użycie statycznych elementów członkowskich w Inner, gdzie i tak Outermożna uzyskać dostęp do dowolnego prywatnego członka Inner(nie poprawia hermetyzacji).

Jeśli chcesz udostępnić coś we wszystkich instancjach Innerutworzonych przez jeden outerobiekt, bardziej sensowne jest umieszczenie ich w Outerklasie jako zwykłych członków.

Nie zgadzam się z opinią, że „statyczna klasa zagnieżdżona jest po prostu klasą najwyższego poziomu”. Myślę, że lepiej jest naprawdę traktować statyczną klasę zagnieżdżoną / klasę wewnętrzną jako część klasy zewnętrznej, ponieważ mają one dostęp do prywatnych członków klasy zewnętrznej. Członkowie klasy zewnętrznej są również „członkami klasy wewnętrznej”. Nie ma więc potrzeby obsługi statycznego elementu członkowskiego w klasie wewnętrznej. Wystarczy zwykły / statyczny element członkowski klasy zewnętrznej.

Don Li
źródło
Zajęcia wewnętrzne również nie są „koniecznością”. Jednak, jako że język nie zapewniają klas wewnętrznych, powinna zapewnić pełną realizację i sensowne z nich.
intrepidis
4

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

Podobnie jak w przypadku metod i zmiennych instancji, klasa wewnętrzna jest powiązana z instancją swojej klasy otaczającej i ma bezpośredni dostęp do metod i pól tego obiektu. Ponadto, ponieważ klasa wewnętrzna jest skojarzona z instancją, nie może ona sama definiować żadnych statycznych elementów członkowskich.

Wyjaśnienie Oracle jest powierzchowne i zawzięte. Ponieważ nie ma technicznego ani składniowego powodu, aby wywłaszczać statyczne składowe w klasie wewnętrznej (jest to dozwolone w innych językach, takich jak C #), motywacją projektantów Javy był prawdopodobnie gust koncepcyjny i / lub kwestia wygody technicznej.

Oto moje spekulacje:

W przeciwieństwie do klas najwyższego poziomu, klasy wewnętrzne są zależne od instancji: instancja klasy wewnętrznej jest skojarzona z instancją każdej z jej klas zewnętrznych i ma bezpośredni dostęp do ich członków. To jest główna motywacja do posiadania ich w Javie. Wyrażony w inny sposób: klasa wewnętrzna jest przeznaczona do tworzenia instancji w kontekście instancji klasy zewnętrznej. Bez instancji klasy zewnętrznej klasa wewnętrzna nie powinna być bardziej użyteczna niż inne elementy instancji klasy zewnętrznej. Nazwijmy to zależnym od instancji duchem klas wewnętrznych.

Sama natura statycznych elementów członkowskich (które NIE są zorientowane obiektowo) koliduje z zależnym od instancji duchem klas wewnętrznych (który JEST zorientowany obiektowo), ponieważ można odwołać się / wywołać statyczny element członkowski klasy wewnętrznej bez wystąpienia klasy zewnętrznej przez przy użyciu kwalifikowanej nazwy klasy wewnętrznej.

Zwłaszcza zmienne statyczne mogą obrażać w jeszcze inny sposób: dwie instancje klasy wewnętrznej, które są powiązane z różnymi instancjami klasy zewnętrznej, miałyby wspólne zmienne statyczne. Ponieważ zmienne są składnikiem stanu, dwie instancje klas wewnętrznych w efekcie współdzieliłyby stan niezależnie od zewnętrznych instancji klas, z którymi są powiązane. Nie jest tak, że jest to niedopuszczalne, aby zmienne statyczne działały w ten sposób (akceptujemy je w Javie jako rozsądny kompromis dla czystości OOP), ale istnieje prawdopodobnie głębsza obraza, którą można popełnić, dopuszczając je w klasach wewnętrznych, których instancje są już połączone z instancjami klas zewnętrznych przez projekt. Zakazanie statycznym członkom w klasach wewnętrznych na korzyść ducha zależnego od instancji przynosi dodatkową korzyść w postaci uprzedzania tego głębszego przestępstwa OOP.

Z drugiej strony, żadne takie przestępstwo nie jest związane ze stałymi statycznymi, które nie konstytuują w znaczący sposób stanu, a więc są dopuszczalne. Dlaczego nie zabronić stałych statycznych dla maksymalnej spójności z duchem zależnym od instancji ? Być może dlatego, że stałe nie muszą zajmować więcej pamięci niż jest to konieczne (jeśli są zmuszane do tego, aby nie były statyczne, są kopiowane do każdej instancji klasy wewnętrznej, co jest potencjalnie marnotrawne). W przeciwnym razie nie potrafię sobie wyobrazić przyczyny wyjątku.

Może nie jest to solidne rozumowanie, ale IMO ma największy sens z pobieżnej uwagi Oracle w tej sprawie.

Benjamin Curtis Drake
źródło
3

Krótka odpowiedź: Model mentalny większości programistów pokazujący, jak działa zakres, nie jest modelem używanym przez javac. Dopasowanie bardziej intuicyjnego modelu wymagałoby dużej zmiany w działaniu javac.

Głównym powodem, dla którego statyczne elementy składowe w klasach wewnętrznych są pożądane, jest czystość kodu - statyczny element członkowski używany tylko przez klasę wewnętrzną powinien mieszkać wewnątrz niej, a nie musi być umieszczony w klasie zewnętrznej. Rozważać:

class Outer {
   int outID;

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

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

Zastanów się, co się dzieje w getID (), gdy używam niekwalifikowanego identyfikatora „outID”. Zakres, w którym pojawia się ten identyfikator, wygląda mniej więcej tak:

Outer -> Inner -> getID()

Tutaj, ponownie, ponieważ tak właśnie działa javac, „Zewnętrzny” poziom zakresu obejmuje zarówno statyczne, jak i instancyjne elementy składowe Outer. Jest to mylące, ponieważ zwykle mówi się nam, aby myśleć o statycznej części klasy jako o kolejnym poziomie zakresu:

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

W ten sposób, oczywiście, staticMethod () widzi tylko statyczne składowe Outer. Ale gdyby tak działał javac, to odwołanie się do zmiennej instancji w metodzie statycznej spowodowałoby błąd „nie można rozwiązać nazwy”. To, co naprawdę się dzieje, to fakt, że nazwa znajduje się w zasięgu, ale następnie włącza się dodatkowy poziom sprawdzania i dowiaduje się, że nazwa została zadeklarowana w kontekście instancji i odwołuje się do niej z kontekstu statycznego.

OK, jak to się ma do klas wewnętrznych? Naiwnie uważamy, że nie ma powodu, dla którego klasy wewnętrzne nie mogą mieć zakresu statycznego, ponieważ wyobrażamy sobie zakres działający w następujący sposób:

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

Innymi słowy, statyczne deklaracje w klasie wewnętrznej i deklaracje instancji w klasie zewnętrznej są objęte zakresem w kontekście wystąpienia klasy wewnętrznej, ale żadna z nich nie jest w rzeczywistości zagnieżdżona w drugiej; zamiast tego oba są zagnieżdżone w statycznym zakresie Outer.

Po prostu nie działa javac - istnieje jeden poziom zasięgu zarówno dla elementów statycznych, jak i instancji, a zakres zawsze jest ściśle zagnieżdżony. Nawet dziedziczenie jest implementowane przez kopiowanie deklaracji do podklasy zamiast rozgałęziania i przeszukiwania zakresu nadklasy.

Aby obsługiwać statyczne elementy składowe klas wewnętrznych, javac musiałby albo podzielić zakresy statyczne i instancji oraz obsługiwać rozgałęzianie i ponowne łączenie hierarchii zakresów , albo musiałby rozszerzyć swoją prostą logiczną ideę „statycznego kontekstu”, aby zmienić, aby śledzić typ kontekstu na wszystkich poziomach klasy zagnieżdżonej w bieżącym zakresie.

Russell Zahniser
źródło
Myślę, że bardziej fundamentalną trudnością związaną z zezwalaniem niestatycznym klasom wewnętrznym na niestatyczne statyczne elementy składowe jest to, że programiści deklarujący takie elementy mogą chcieć powiązać je z wystąpieniami klasy zewnętrznej lub mieć je naprawdę statyczne. W przypadkach, gdy konstrukcję - jeśli legalną - można rozsądnie określić jako oznaczającą jedną z dwóch różnych rzeczy, i gdy obie te rzeczy można wyrazić na inne jednoznaczne sposoby, określenie tej konstrukcji jako nielegalnej jest często lepsze niż określenie jej jako mające którekolwiek znaczenie.
supercat,
3

Dlaczego nie możemy mieć metody statycznej w niestatycznej klasie wewnętrznej?

Uwaga: niestatyczna klasa zagnieżdżona jest nazywana klasą wewnętrzną, więc nie ma non-static inner classtakiej klasy.

Instancja klasy wewnętrznej nie istnieje bez odpowiedniego wystąpienia klasy zewnętrznej. Klasa wewnętrzna nie może deklarować statycznych elementów członkowskich innych niż stałe czasu kompilacji. Gdyby było to dozwolone, istniałaby niejednoznaczność co do znaczenia static. W takim przypadku byłyby pewne niejasności:

  1. Czy to oznacza, że ​​w maszynie wirtualnej jest tylko jedna instancja?
  2. Czy tylko jedna instancja na obiekt zewnętrzny?

Dlatego zapewne konstruktorzy zdecydowali się nie zajmować się tym problemem.

Jeśli uczynię wewnętrzną klasę statyczną, to działa. Czemu ?

Ponownie nie można uczynić klasy wewnętrznej statyczną, a raczej zadeklarować klasę statyczną jako zagnieżdżoną. W takim przypadku ta zagnieżdżona klasa jest w rzeczywistości częścią klasy zewnętrznej i może mieć statyczne elementy członkowskie bez żadnego problemu.

akhil_mittal
źródło
3

Temat ten zwrócił na siebie uwagę wielu, ale postaram się wyjaśnić w najprostszych słowach.

Po pierwsze, w odniesieniu do http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1 , klasa lub interfejs jest inicjowany bezpośrednio przed pierwszym wystąpieniem / wywołaniem dowolnego elementu członkowskiego, który jest poprzedzony słowem kluczowym static.

  1. Tak więc, jeśli pogodzimy się ze statycznym składnikiem w klasie wewnętrznej, doprowadzi to do zainicjowania klasy wewnętrznej, niekoniecznie klasy zewnętrznej / otaczającej. Tak więc utrudniamy sekwencję inicjalizacji klas.

  2. Weź również pod uwagę fakt, że niestatyczna klasa wewnętrzna jest powiązana z wystąpieniem klasy otaczającej / zewnętrznej. Zatem skojarzenie z instancją będzie oznaczać, że klasa wewnętrzna będzie istnieć wewnątrz instancji klasy Outer i będzie się różnić między instancjami.

Upraszczając, aby uzyskać dostęp do statycznego elementu członkowskiego, potrzebujemy wystąpienia klasy Outer, z której ponownie będziemy musieli utworzyć wystąpienie niestatycznej klasy wewnętrznej. Statyczne elementy członkowskie nie powinny być powiązane z instancjami, dlatego pojawia się błąd kompilacji.

Skazany 93
źródło
2

Klasa wewnętrzna to coś zupełnie innego niż statyczna klasa zagnieżdżona, chociaż obie mają podobną składnię. Statyczne klasy zagnieżdżone są tylko środkiem do grupowania, podczas gdy klasy wewnętrzne mają silne powiązanie - i dostęp do wszystkich wartości - ich klasy zewnętrznej. Powinieneś być pewien, dlaczego chcesz użyć klasy wewnętrznej, a wtedy powinno być całkiem naturalne, której z nich musisz użyć. Jeśli chcesz zadeklarować metodę statyczną, jest to prawdopodobnie statyczna klasa zagnieżdżona, którą i tak chcesz.

BYĆ
źródło
Benedikt, co masz na myśli, mówiąc, że „statyczne klasy zagnieżdżone są tylko środkiem do grupowania”?
Ankur
0

załóżmy, że istnieją dwa wystąpienia klasy zewnętrznej i oba mają instancję klasy wewnętrznej. Teraz, jeśli klasa wewnętrzna ma jeden statyczny element członkowski, zachowa tylko jedną kopię tego elementu w obszarze sterty. w tym przypadku oba obiekty klasy zewnętrznej będą odnosić się do this pojedyncza kopia i mogą ją zmienić razem. Może to spowodować sytuację "Brudnego odczytu", dlatego ta Java nie zastosowała tego ograniczenia. Innym mocnym punktem na poparcie tego argumentu jest to, że java dopuszcza tutaj ostateczne statyczne elementy członkowskie, których wartości nie mogą być zmieniono z dowolnego obiektu klasy zewnętrznej. Proszę, pozwól mi, jeśli się mylę.

malajski
źródło
0

Po pierwsze, dlaczego ktoś chce zdefiniować statyczny element członkowski w niestatycznej klasie wewnętrznej? odpowiedź brzmi: tak, że zewnętrzna składowa klasy może używać tych statycznych składowych tylko z wewnętrzną nazwą klasy, prawda?

Ale w tym przypadku możemy bezpośrednio zdefiniować element członkowski w klasie zewnętrznej. który będzie powiązany ze wszystkimi obiektami klasy wewnętrznej, wewnątrz instancji klasy zewnętrznej.

jak poniższy kod,

public class Outer {

  class Inner {

    public static void method() {

    }

  }

}

można napisać w ten sposób

public class Outer {

  void method() {

   }

   class Inner {


  }

}

Więc moim zdaniem, aby nie komplikować kodu, projektant java nie zezwala na tę funkcjonalność lub możemy zobaczyć tę funkcjonalność w przyszłych wersjach z kilkoma dodatkowymi funkcjami.

Vishnu Saini
źródło
0

Spróbuj potraktować klasę jako normalne pole, wtedy zrozumiesz.

//something must be static. Suppose something is an inner class, then it has static keyword which means it's a static class
Outer.something 
user1888955
źródło
-1

Nie ma sensu mieć statycznych członków klasy wewnętrznej, ponieważ w pierwszej kolejności nie będziesz mieć do nich dostępu.

Pomyśl o tym, aby uzyskać dostęp do statycznego elementu członkowskiego, którego używasz nazwa_klasy.memberName, w naszym przypadku powinno to być coś w rodzaju externalclassName.innerclassName.memberName ,,, teraz widzisz, dlaczego wewnętrzna klasa musi być statyczna ....

Creative_Cimmons
źródło
-2

Dozwolone są statyczne metody w statycznych klasach zagnieżdżonych. Na przykład

public class Outer {

  public static class Inner {

    public static void method() {

    }
  }
}
mR_fr0g
źródło