W Javie możesz zdefiniować wiele klas najwyższego poziomu w jednym pliku, pod warunkiem, że co najwyżej jedna z nich jest publiczna (patrz JLS §7.6 ). Zobacz na przykład poniżej.
Czy istnieje schludny nazwa dla tej techniki (analogiczny do
inner
,nested
,anonymous
)?JLS mówi, że system może wymusić ograniczenie, że te klasy drugorzędne nie mogą być
referred to by code in other compilation units of the package
, np. Nie mogą być traktowane jako prywatne. Czy to naprawdę coś zmienia się między implementacjami Java?
np. PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
Odpowiedzi:
Moja sugerowana nazwa tej techniki (w tym wielu klas najwyższego poziomu w jednym pliku źródłowym) to „bałagan”. Poważnie, nie sądzę, że to dobry pomysł - zamiast tego użyłbym typu zagnieżdżonego. Wciąż łatwo jest przewidzieć, w którym pliku źródłowym jest. Nie sądzę jednak, aby istniało oficjalne określenie tego podejścia.
Jeśli chodzi o to, czy to rzeczywiście zmienia się między implementacjami - bardzo w to wątpię, ale jeśli unikniesz tego, nigdy nie będziesz musiał się tym przejmować :)
źródło
public int[] foo(int x)[] { return new int[5][5]; }
też, nawet jeśli to jest ważne.)javac nie aktywnie tego zabrania, ale ma ograniczenia, które w zasadzie oznaczają, że nigdy nie chciałbyś odwoływać się do klasy najwyższego poziomu z innego pliku, chyba że ma taką samą nazwę jak plik, w którym się znajduje.
Załóżmy, że masz dwa pliki, Foo.java i Bar.java.
Foo.java zawiera:
Bar.java zawiera:
Powiedzmy również, że wszystkie klasy są w tym samym pakiecie (a pliki znajdują się w tym samym katalogu).
Co się stanie, jeśli Foo.java odnosi się do Baz, ale nie Bar, i spróbujemy skompilować Foo.java? Kompilacja kończy się niepowodzeniem z takim błędem:
Ma to sens, jeśli się nad tym zastanowić. Jeśli Foo.java odnosi się do Baz, ale nie ma Baz.java (lub Baz.class), to w jaki sposób javac może wiedzieć, w którym pliku źródłowym szukać?
Jeśli zamiast tego powiesz javacowi, aby skompilował Foo.java i Bar.java w tym samym czasie, lub nawet jeśli wcześniej skompilowałeś Bar.java (pozostawiając Baz.class, gdzie javac może go znaleźć), to ten błąd zniknie. To sprawia, że proces kompilacji wydaje się bardzo zawodny i łuszczący się.
Ponieważ rzeczywiste ograniczenie, które jest bardziej jak „nie odnosi się do klasy najwyższego poziomu z innego pliku, chyba że ma taką samą nazwę jak plik, w którym się znajduje, lub odnosi się to również do klasy, która znajduje się w tym samym pliku o nazwie to samo, co plik „jest trochę trudny do naśladowania, ludzie zwykle stosują o wiele prostszą (choć bardziej rygorystyczną) konwencję polegającą na umieszczeniu tylko jednej klasy najwyższego poziomu w każdym pliku. Jest to również lepsze, jeśli kiedykolwiek zmienisz zdanie na temat tego, czy klasa powinna być publiczna, czy nie.
Czasami naprawdę istnieje dobry powód, dla którego każdy robi coś w określony sposób.
źródło
Uważam po prostu zadzwonić
PrivateImpl
, co to jest: anon-public top-level class
. Możesz również zadeklarowaćnon-public top-level interfaces
.np. gdzie indziej na SO: niepubliczna klasa najwyższego poziomu vs. statyczna klasa zagnieżdżona
Jeśli chodzi o zmiany w zachowaniu między wersjami, była dyskusja na temat czegoś, co „działało idealnie” w 1.2.2. ale przestał działać w 1.4 na forum Sun: Kompilator Java - nie można zadeklarować w pliku niepublicznych klas najwyższego poziomu .
źródło
non-public top level class
jedyną klasę w pliku, więc to nie rozwiązuje problemu wielości.secondary top level types
.Możesz mieć tyle zajęć, ile chcesz
źródło
Wieloklasowe demo jednego pliku.
Nie znam żadnych, które nie mają tego ograniczenia - wszystkie kompilatory oparte na plikach nie pozwolą ci odwoływać się do klas kodu źródłowego w plikach, które nie mają takich samych nazw jak nazwa klasy. (jeśli skompilujesz plik wielu klas i umieścisz klasy na ścieżce klasy, to dowolny kompilator je znajdzie)
źródło
Według Effective Java 2. wydanie (pozycja 13):
Zagnieżdżona klasa może być statyczna lub niestatyczna w zależności od tego, czy klasa członka potrzebuje dostępu do otaczającej instancji (pozycja 22).
źródło
Tak, możesz, z publicznymi statycznymi członkami zewnętrznej klasy publicznej, tak jak:
i inny plik, który odwołuje się do powyższego:
umieść je w tym samym folderze. Połącz z:
i biegnij z:
źródło
Tylko do Twojej wiadomości, jeśli używasz Java 11+, istnieje wyjątek od tej reguły: jeśli uruchamiasz plik Java bezpośrednio ( bez kompilacji ). W tym trybie nie ma ograniczeń co do jednej klasy publicznej na plik. Jednak klasa z
main
metodą musi być pierwsza w pliku.źródło
Nie, nie możesz. Ale jest bardzo możliwe w Scali:
źródło