Ich habe eine Frage, auf die ich keine Antwort gefunden habe, mit Ausnahme der folgenden Antwort, die nicht meinen Anforderungen entspricht:
"Weil James Gosling nicht wollte"
Ich weiß, dass Java Schnittstellen haben kann (nur reine virtuelle Funktionen, keine Attribute), aber es ist nicht genau dasselbe wie Klassendefinitionen.
Antworten:
Das ist jedoch die richtige Antwort. Das Sprachdesign-Team (Gosling, Sheridan, Naughton, später Bill Joy, Ken Arnold usw.) entschied, dass Header mehr Probleme verursachten, als sie lösten . Also haben sie sie entworfen und gezeigt, dass sie eine vollkommen nützliche Sprache schaffen können, ohne dass sie benötigt werden.
In Abschnitt 2.2.1 des Java Language Environment-Whitepapers heißt es :
Redundante Definitionen, Synchronisierung von Dateien, Konflikte mit Definitionen und versteckte Definitionen - keine davon tritt in Java auf, da Sie keine Header haben. Wenn Sie eine bloße Klassendefinition anzeigen möchten, können Sie diese direkt aus einer .java-Datei generieren - z. B. zeigen die meisten IDEs die Struktur einer Klasse in einer Seitenleiste an, was auf dasselbe hinausläuft.
quelle
In C ++ besteht keine wirkliche Notwendigkeit, die Klassendefinitionen und Deklarationen in separaten Dateien zu haben. Es bedeutet nur, dass Sie zumindest in den C-Tagen den Code in einem einzigen Scan von oben nach unten analysieren können. Auf Maschinen ohne Direktzugriffsspeicher war dies eine große Sache!
Wenn Sie über Header verfügen, können Sie die Schnittstelle auch in Ihrer Codebibliothek veröffentlichen, indem Sie den Header bereitstellen, ohne den Quellcode preisgeben zu müssen. Leider müssen Sie in C ++ auch die privaten Datenelemente offenlegen, was zu Lösungen wie dem Horror von Pimpl geführt hat .
Es gab Versuche, eine C ++ - Umgebung zu erstellen, in der alles in einer Datenbanktypstruktur gespeichert war und keine Dateien vorhanden waren, die sich jedoch nicht durchsetzten.
quelle
Wegen des DRY- Prinzips. In Java sind die Informationen, die zur Verwendung von Klassen in einem Paket (oder einer Klasse) erforderlich sind, in der .class-Datei enthalten. Wenn Sie separate Header-Dateien erstellen, die dieselben Informationen enthalten, müssen Sie diese an zwei Stellen wiederholen.
quelle
In jeder Sprache - es gibt zwei Stufen zum Erstellen des endgültigen Binärcodes - Kompilieren und Verknüpfen (natürlich wird geladen, aber das hat hier keine großen Auswirkungen). Zum Zeitpunkt des Kompilierens braucht man nur Hooks (die Spezifikation der Funktionen, die aufgerufen werden) an die entsprechende Stelle zu setzen. Linker tritt tatsächlich bei sie , wenn beide echten Codes verfügbar sind. Bisher gibt es keinen Unterschied zwischen C ++ und Java.
Es ist jedoch ein Bedarf für C ++ haben Deklaration und Definition getrennt. Wenn Sie die Implementierung im Header beibehalten und die Headerdatei ändert, muss der damit verknüpfte Code neu kompiliert werden. Wenn sich die Definition in einer separaten Datei befindet, muss der Code nur erneut verknüpft werden.
Verstehen Sie, dass C ++ die Option hat, statisch zu sein Verknüpfungen verfügt, die impliziert, dass der Objektcode zusammen mit der aufrufenden Anwendung korrigiert wird. Bitte beachten Sie, dass es sowohl in C als auch in C ++ nicht ungültig ist, in der Header-Datei zu programmieren oder sogar #include zu verwenden. Es bedeutet nur, dass Sie sich Gedanken darüber machen müssen, wie die Verknüpfung mit diesen Objektdateien erfolgt.
Die Situation in Java ist sehr unterschiedlich. Jede Klassendatei wird mit einer .class-Datei kompiliert. In der Tat die Notwendigkeit der Kompilierung von Aufruferklassenfunktionen, die als Header-Abschnitt in der .class-Datei dienen. In Java erfolgt die endgültige Verknüpfung jedoch nur innerhalb der Runtime (der virtuellen Maschine), wenn der Bytecode der Klassendatei angegeben ist.
Sieh dies und das
quelle
Tatsächlich sind die Schnittstellen und Includes die Header. Die Definitionen sind daher identisch mit den Binärdateien und können nicht synchron sein. Dies ist eine der besten Entwurfsentscheidungen in Java, aber es ist ein kleines Ärgernis, dass es keine Möglichkeit gibt, diese Deklarationen für Kompaktheit und Konsistenz zu bündeln.
quelle
Ein guter Grund für Includes ist, den Code, den Sie möglicherweise wiederverwenden möchten (z. B. allgemeine Definitionen), von dem Code zu trennen, der für ein bestimmtes Projekt spezifisch ist. Java möchte, dass Sie nur eine Klasse oder Schnittstelle pro Datei angeben, und dies reduziert größtenteils den Bedarf an eingeschlossenen Headern - denn Sie werden die gemeinsam genutzten Teile bereits in ihren eigenen Dateien speichern.
Außerdem möchten Compiler und Buildsysteme möglicherweise vorkompilierte Header zwischenspeichern, um zu vermeiden, dass sie mehrmals analysiert werden.
quelle