In Java können Sie mehrere Klassen der obersten Ebene in einer einzigen Datei definieren, vorausgesetzt, dass höchstens eine davon öffentlich ist (siehe JLS §7.6 ). Siehe unten zum Beispiel.
Gibt es einen ordentlichen Namen für diese Technik (analog
inner
,nested
,anonymous
)?Das JLS sagt, dass das System möglicherweise die Einschränkung erzwingt, dass diese sekundären Klassen nicht sein können
referred to by code in other compilation units of the package
, z. B. können sie nicht als paketprivat behandelt werden. Ändert sich das wirklich zwischen Java-Implementierungen?
zB PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
Antworten:
Mein vorgeschlagener Name für diese Technik (einschließlich mehrerer Klassen der obersten Ebene in einer einzigen Quelldatei) wäre "Chaos". Im Ernst, ich denke nicht, dass es eine gute Idee ist - ich würde stattdessen in dieser Situation einen verschachtelten Typ verwenden. Dann ist es immer noch leicht vorherzusagen, in welcher Quelldatei sie sich befindet. Ich glaube jedoch nicht, dass es einen offiziellen Begriff für diesen Ansatz gibt.
Ob sich dies tatsächlich zwischen den Implementierungen ändert - ich bezweifle es sehr, aber wenn Sie es überhaupt vermeiden, müssen Sie sich nie darum kümmern :)
quelle
public int[] foo(int x)[] { return new int[5][5]; }
so gut zu schreiben , obwohl das gültig ist.)javac verbietet dies nicht aktiv, hat jedoch eine Einschränkung, die so ziemlich bedeutet, dass Sie niemals auf eine Klasse der obersten Ebene aus einer anderen Datei verweisen möchten, es sei denn, sie hat denselben Namen wie die Datei, in der sie sich befindet.
Angenommen, Sie haben zwei Dateien, Foo.java und Bar.java.
Foo.java enthält:
Bar.java enthält:
Angenommen, alle Klassen befinden sich im selben Paket (und die Dateien befinden sich im selben Verzeichnis).
Was passiert, wenn Foo.java auf Baz, aber nicht auf Bar verweist und wir versuchen, Foo.java zu kompilieren? Die Kompilierung schlägt mit einem Fehler wie dem folgenden fehl:
Dies ist sinnvoll, wenn Sie darüber nachdenken. Wenn Foo.java auf Baz verweist, aber keine Baz.java (oder Baz.class) vorhanden ist, wie kann javac wissen, in welcher Quelldatei gesucht werden soll?
Wenn Sie stattdessen javac anweisen, Foo.java und Bar.java gleichzeitig zu kompilieren, oder wenn Sie zuvor Bar.java kompiliert haben (die Baz.class dort belassen, wo javac sie finden kann), verschwindet dieser Fehler. Dadurch fühlt sich Ihr Erstellungsprozess jedoch sehr unzuverlässig und schuppig an.
Weil die eigentliche Einschränkung eher so lautet: "Verweisen Sie nicht auf eine Klasse der obersten Ebene aus einer anderen Datei, es sei denn, sie hat denselben Namen wie die Datei, in der sie sich befindet, oder Sie beziehen sich auch auf eine Klasse, die sich in derselben Datei befindet, die benannt ist Das Gleiche wie die Datei "ist schwer zu befolgen. Die Leute gehen normalerweise mit der viel einfacheren (wenn auch strengeren) Konvention vor, nur eine Klasse der obersten Ebene in jede Datei einzufügen. Dies ist auch besser, wenn Sie jemals Ihre Meinung ändern, ob eine Klasse öffentlich sein soll oder nicht.
Manchmal gibt es wirklich einen guten Grund, warum jeder etwas auf eine bestimmte Weise tut.
quelle
Ich glaube, Sie nennen einfach,
PrivateImpl
was es ist: anon-public top-level class
. Sie können auch deklarierennon-public top-level interfaces
.zB anderswo auf SO: Nicht öffentliche Klasse der obersten Ebene gegen statisch verschachtelte Klasse
In Bezug auf Verhaltensänderungen zwischen Versionen gab es diese Diskussion über etwas, das in 1.2.2 "perfekt funktioniert" hat. Die Arbeit in Version 1.4 im Sun-Forum wurde jedoch eingestellt: Java Compiler - Nicht öffentliche Klassen der obersten Ebene in einer Datei können nicht deklariert werden .
quelle
non-public top level class
die einzige Klasse in einer Datei sein können, sodass die Vielzahl nicht berücksichtigt wird.secondary top level types
.Sie können so viele Klassen haben, wie Sie möchten
quelle
Demo mit mehreren Dateien und mehreren Dateien.
Mir sind keine bekannt, die diese Einschränkung nicht haben. Bei allen dateibasierten Compilern können Sie nicht auf Quellcodeklassen in Dateien verweisen, die nicht den gleichen Namen wie der Klassenname haben. (Wenn Sie eine Datei mit mehreren Klassen kompilieren und die Klassen in den Klassenpfad einfügen, werden sie von jedem Compiler gefunden.)
quelle
Laut Effective Java 2nd Edition (Punkt 13):
Die verschachtelte Klasse kann statisch oder nicht statisch sein, je nachdem, ob die Mitgliedsklasse Zugriff auf die einschließende Instanz benötigt (Element 22).
quelle
Ja, Sie können mit öffentlichen statischen Mitgliedern in einer äußeren öffentlichen Klasse wie folgt:
und eine andere Datei, die auf das oben Genannte verweist:
Legen Sie sie in den gleichen Ordner. Kompilieren mit:
und laufen mit:
quelle
Nur zu Ihrer Information, wenn Sie Java 11+ verwenden, gibt es eine Ausnahme von dieser Regel: Wenn Sie Ihre Java-Datei direkt ausführen ( ohne Kompilierung ). In diesem Modus gibt es keine Einschränkung für eine einzelne öffentliche Klasse pro Datei. Die Klasse mit der
main
Methode muss jedoch die erste in der Datei sein.quelle
Nein, das kannst du nicht. Aber in Scala ist es sehr gut möglich:
quelle