In Java erhalten wir bei der Kompilierung eine .class-Datei für jede Klasse (einschließlich verschachtelter Klassen und Schnittstellen), die in der Quelldatei definiert ist. Was ist der Grund für diese mehrfache .class-Dateigeneration?
Ist es für die Vereinfachung der Wiederverwendbarkeit der Klasse?
Warum nicht eine Klasse für eine .java-Datei generieren?
Als Antwort auf @ Jon Skeets rhetorische Frage:
Eine andere Klasse bezieht sich dann auf Bar, also benötigt die JVM den Code dafür ... wie würden Sie vorschlagen, dass sie die Datei findet?
Nehmen Sie (hypothetisch) an, dass das Java-Klassendateiformat verschachtelte / innere Klassen darstellt, indem Sie sie in die Klassendatei für die äußerste Klasse einbetten. Der binäre Name für den Balken lautet " Lsome/pkg/Foo$Bar;
". Der Klassenlader könnte den Namen in das Zeichen " $
" aufteilen, den ersten Teil verwenden, um die Klassendatei für Foo zu finden und dann zur eingebetteten Bar-Klassenrepräsentation navigieren.
Ich denke, dass der wahre Grund dafür, dass innere / verschachtelte Klassen separate Klassendateien haben, historisch ist. IIRC, Java 1.0 unterstützte verschachtelte oder innere Klassen nicht und daher mussten die entsprechenden Klassendateiformate nicht mit ihnen umgehen. Als Java 1.1 erstellt wurde (unterstützt interne / verschachtelte Klassen), wollte Sun, dass das classfile-Format mit den vom Java 1.0-Compiler erzeugten Klassendateien kompatibel ist. Daher entschieden sie sich dafür, innere / verschachtelte Klassen als separate Klassendateien zu implementieren, indem sie das reservierte Zeichen " $
" im binären Klassennamen verwenden.
Ein zweiter möglicher Grund ist, dass das flache Format das Laden von Klassen im Vergleich zu einem hypothetischen eingebetteten Format vereinfacht.
Und schließlich gab es (und gibt es immer noch) keinen zwingenden Grund dafür, dass sie KEIN flaches Dateiformat verwenden. Es verursacht vielleicht ein wenig Kopfzerbrechen, wenn ein Programmierer innere Klassen mit Class.forName()
laden möchte, aber das ist ziemlich selten ... und die Lösung ist einfach.
Die JVM muss in der Lage sein, den Code für eine gegebene Klasse unter Angabe ihres Namens zu finden. Wenn zwischen dem Quelldateinamen und dem Codedateinamen möglicherweise keine Beziehung besteht und Sie möchten, dass der Dateiname des Codes auf dem source -Dateinamen basiert, wie würden Sie dann den Code laden?
Als Beispiel: Angenommen, ich würde Foo.java kompilieren, das die Klasse Bar enthält.
Eine andere Klasse bezieht sich dann auf Bar, also benötigt die JVM den Code dafür ... wie würden Sie vorschlagen, dass sie die Datei findet?
Beachten Sie, dass es in .NET eine separate Bereitstellungseinheit gibt, die Assembly genannt wird - und ein Verweis auf einen Typ auch den Assemblynamen enthält, der sich jedoch etwas von dem unterscheidet, was Sie vorgeschlagen haben.
Das ist eine Designentscheidung bezüglich einer Kompilierungseinheit, die von den Entwicklern getroffen wurde. Zusammengestellte Klassen werden normalerweise in einer JAR-Datei kombiniert.
Auszug aus der Java-Sprachspezifikation
7.3 Kompilierungseinheiten CompilationUnit ist das Zielsymbol (§2.1) für die syntaktische Grammatik (§2.3) von Java-Programme.
Typen, die in verschiedenen Kompilierungseinheiten deklariert sind, können kreisförmig voneinander abhängen. Ein Java-Compiler muss alle diese Typen gleichzeitig kompilieren.
Tags und Links java