Warum schreibt Java den Dateinamen nicht in args?


20

In C und C ++ enthält die main-Methode den Dateinamen an der ersten Position des Arrays bei argv [0]. In Java ist der Dateiname jedoch nicht im Array args string enthalten.

Gibt es dafür einen praktischen Grund? Ich verstehe, dass dies die Iteration durch Befehlszeilenargumente 0-basiert anstelle von 1-basiert macht, aber gibt es einen Vorteil? Wurde der Dateiname nur als nutzlos angesehen?

Antworten:


17

In einigen Fällen kann ein Programm auf unterschiedliche Weise ausgeführt werden und ein unterschiedliches Verhalten beim Aufruf zeigen. Wenn Sie vimas aufrufen vi, wird es in einem Kompatibilitätsmodus ausgeführt. Manchmal muss versucht werden, eine Version mehrerer verwandter Programme zu verwalten - zum Beispiel mailqund newaliasesauf vielen Unix-Systemen ist dies eine Verknüpfung, sendmaildamit diese Programme synchron bleiben.


Java-Programme werden normalerweise wie folgt aufgerufen:

% java -jar foo.jar args
% java Foo args

In der ersten Version verfügen Sie über eine Manifest-Datei, die die Hauptklasse angibt. In der zweiten Version wird die Hauptmethode in der Klasse ausgeführt, die Foosich im Klassenpfad befindet.

Die für Java angezeigten Informationen sind entweder ein Pfad zum Jar oder der Name der aufgerufenen Klasse.

Die Position des Glases ist nicht wichtig genug, um Code zu verwenden (und war eigentlich nicht Teil der ursprünglichen Spezifikation). Ein Jar kann wirklich einen beliebigen Namen haben und enthält häufig Versionsnummern. Darüber hinaus gibt es keine Garantie dafür, dass die Klasse sogar in einer .jar-Datei gespeichert wurde (sie hätte extrahiert werden können).

Das Aufrufen einer Java-Anwendung mit -jarhat nur eine Möglichkeit, sie aufzurufen - die im Manifest definierte Klasse. Es kann nicht umbenannt werden.

Die andere Möglichkeit, es mit dem Klassennamen aufzurufen, zeigt direkt auf die Ausführungseinheit. Darüber hinaus kann es nicht mehrfach benannt werden - Sie können nicht Bar.classden Code dafür haben , der class Fooeinfach nicht so funktioniert.

Dies sollte zeigen, dass es wirklich keinen Sinn macht, die Informationen von argv[0]C an eine Java-Anwendung weiterzugeben - sie sind entweder javabedeutungslos und willkürlich oder der Name der Klasse, die aufgerufen wird (Sie führen bereits Code aus) von (Sie könnten so etwas tun, getClass().getEnclosingClass().getName()wenn Sie verzweifelt wären ...)).

Hier gibt es einen Punkt, an dem Sie mehrere Main-Methoden in Klassen in einer .jar-Datei oder im Klassenpfad definieren können. Und man könnte sie sich anders verhalten lassen, als gäbe es eine Reihe von if-Anweisungen, die darauf basieren, was argv[0]war.

Ich hatte in der Vergangenheit einen ähnlichen Code, java -cp Foo.jar com.me.foo.Testder die TestMain-Methode der Klasse aufrief und nicht die, die in der im Manifest definierten Methode definiert ist.


Es muss mehr als das geben. In C # enthalten die Parameter nicht den Dateinamen, aber die Anwendung wird normalerweise direkt ausgeführt foo.exe.
Svick

@svick Ich kenne C # nicht und weiß auch nicht, wie eine Exe verpackt ist. In einigen Betriebssystemen können Sie eine JAR-Datei ausführbar machen (siehe diese ), die den im Manifest definierten Einstiegspunkt startet. Ähnliche Dinge können für C # durchgeführt werden. Das Wichtigste ist, dass Sie den Einstiegspunkt nicht durch Ändern des Dateinamens ändern können und der Dateiname nicht für andere Teile der Anwendung (außerhalb des Klassenladeprogramms) vorgesehen ist.

@nqzero ( context ) - Wenn ich java com.me.Fooals Befehlszeile angebe , wird die Methode com.me.Foo.main(String...)aufgerufen. Daran führt kein Weg vorbei. Und ich weiß, dass es Foo ist, der angerufen wird - es gibt keinen Grund, dies in argument zu verankern. Es wäre eine rein redundante Information. Sicher, es könnte in der Oberklasse sein, aber ich habe die triviale Möglichkeit, es mit den gewünschten Informationen darüber abzufangen, was der Befehlszeilenaufruf war - keine Notwendigkeit, es in argv zu setzen.

... und bitte denken Sie daran, 50 Wiederholungen und Kommentare zu erhalten, anstatt Änderungen an der Antwort vorzuschlagen. Es ist ein sehr schlechter Weg, um Probleme mit einem bestimmten Beitrag anzusprechen.

Manchmal ist das Verhalten radikal anders. wput zum Beispiel ist eigentlich wget.
McKenzm

-4

Eigentlich hat es keinen Vorteil, es hängt wirklich von der Syntax der verwendeten Programmiersprache ab, ob sie 0-basiert oder 1-basiert ist. Die Variable (Sie bezeichnen sie als Dateiname) hängt auch von der Sprache ab. Sie kann in anderen Sprachen unterschiedlich sein. Befolgen Sie einfach die korrekte Syntax der von Ihnen verwendeten Sprache.


1
Wie beantwortet dies die gestellte Frage?
gnat
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.