Java Language
Der Java-Befehl - 'Java' und 'Javaw'
Suche…
Syntax
java [ <opt> ... ] <class-name> [ <argument> ... ]
java [ <opt> ... ] -jar <jar-file-pathname> [ <argument> ... ]
Bemerkungen
Der java
Befehl wird zum Ausführen einer Java-Anwendung von der Befehlszeile aus verwendet. Es ist als Bestandteil von Java SE JRE oder JDK verfügbar.
Auf Windows-Systemen gibt es zwei Varianten des java
Befehls:
- Die
java
Variante startet die Anwendung in einem neuen Konsolenfenster. - Die
javaw
Variante startet die Anwendung, ohne ein neues Konsolenfenster zu erstellen.
Auf anderen Systemen (z. B. Linux, Mac OSX, UNIX) wird nur der java
Befehl bereitgestellt, und es wird kein neues Konsolenfenster geöffnet.
Das <opt>
-Symbol in der Syntax kennzeichnet eine Option in der java
Befehlszeile. Die Themen "Java-Optionen" und "Heap- und Stack-Sizing-Optionen" behandeln die am häufigsten verwendeten Optionen. Weitere werden im Thema JVM-Flags behandelt .
Ausführen einer ausführbaren JAR-Datei
Ausführbare JAR-Dateien sind der einfachste Weg, Java-Code in einer einzigen Datei zusammenzustellen, die ausgeführt werden kann. * (Anmerkung der Redaktion: Die Erstellung von JAR-Dateien sollte in einem eigenen Thema behandelt werden.) *
Vorausgesetzt, Sie haben eine ausführbare JAR-Datei mit dem Pfadnamen <jar-path>
, sollten Sie sie wie folgt ausführen können:
java -jar <jar-path>
Wenn für den Befehl Befehlszeilenargumente erforderlich sind, fügen Sie sie nach dem <jar-path>
. Zum Beispiel:
java -jar <jar-path> arg1 arg2 arg3
Wenn Sie zusätzliche JVM-Optionen in der java
Befehlszeile -jar
müssen, müssen diese vor der Option -jar
. Beachten Sie, dass eine Option -cp
/ -classpath
ignoriert wird, wenn Sie -jar
. Der Klassenpfad der Anwendung wird durch das Manifest der JAR-Datei bestimmt.
Ausführen von Java-Anwendungen über eine "main" -Klasse
Wenn eine Anwendung nicht als ausführbare JAR-Datei gepackt wurde, müssen Sie den Namen einer Einstiegspunktklasse in der java
Befehlszeile angeben.
Die HelloWorld-Klasse ausführen
Das Beispiel "HelloWorld" wird unter Erstellen eines neuen Java-Programms beschrieben . Sie besteht aus einer einzigen Klasse namens HelloWorld
die die Anforderungen für einen Einstiegspunkt erfüllt.
Unter der Annahme, dass sich die (kompilierte) Datei "HelloWorld.class" im aktuellen Verzeichnis befindet, kann sie wie folgt gestartet werden:
java HelloWorld
Einige wichtige Dinge zu beachten sind:
- Wir müssen den Namen der Klasse angeben, nicht den Pfadnamen für die ".class" -Datei oder die ".java" -Datei.
- Wenn die Klasse in einem Paket deklariert ist (wie bei den meisten Java-Klassen), muss der Klassenname, den wir dem Befehl
java
angeben, der vollständige Klassenname sein. WennSomeClass
beispielsweise im PaketSomeClass
deklariert ist,com.example
der vollständige Klassennamecom.example.SomeClass
.
Klassenpfad angeben
Wenn wir nicht in der java -jar
Befehlssyntax verwenden, sucht der java
Befehl nach der zu ladenden Klasse, indem er den Klassenpfad durchsucht. siehe The Classpath . Der obige Befehl setzt voraus, dass der Standardklassenpfad das aktuelle Verzeichnis ist (oder das aktuelle Verzeichnis enthält). Wir können dies expliziter machen, indem wir den Klassenpfad -cp
, der mit der Option -cp
verwendet werden -cp
.
java -cp . HelloWorld
Dies bedeutet, dass das aktuelle Verzeichnis (worauf sich "." Bezieht) der einzige Eintrag im Klassenpfad ist.
Die Option -cp
ist eine Option, die vom Befehl java
verarbeitet wird. Alle Optionen, die für den java
Befehl vorgesehen sind, sollten vor dem Klassennamen stehen. Alles nach der Klasse wird als Befehlszeilenargument für die Java-Anwendung behandelt und an die Anwendung in der String[]
, die an die main
wird.
(Wenn keine Option -cp
ist, verwendet java
den Klassenpfad, der von der Umgebungsvariablen CLASSPATH
wird. Wenn diese Variable nicht festgelegt oder leer ist, verwendet java
"." Als Standardklassenpfad.)
Einstiegspunktklassen
Eine Java - Entry-Point - Klasse hat ein main
mit folgenden Signatur und Modifikatoren:
public static void main(String[] args)
Randbemerkung: aufgrund der Funktionsweise von Arrays kann es auch sein
(String args[])
Wenn der java
Befehl die virtuelle Maschine startet, lädt sie die angegebenen Einstiegsklassen und versucht, nach main
zu suchen. Bei Erfolg werden die Argumente von der Befehlszeile in Java- String
Objekte konvertiert und zu einem Array zusammengefügt. Wenn main
wie diese aufgerufen wird, wird das Array nicht null
und wird keine enthalten null
Einträge.
Eine gültige Einstiegspunkt-Klassenmethode muss Folgendes tun:
-
main
(Groß- und Kleinschreibung beachten) - Seien Sie
public
undstatic
- Einen
void
Rückgabetyp haben - Habe ein einzelnes Argument mit einem Array
String[]
. Das Argument muss vorhanden sein und nicht mehr als ein Argument ist zulässig. - Seien Sie generisch: Typparameter sind nicht zulässig.
- Verfügt über eine nicht generische Klasse der obersten Ebene (nicht verschachtelt oder inner)
Es ist üblich, die Klasse als public
zu deklarieren, dies ist jedoch nicht unbedingt erforderlich. Ab Java 5 kann der Argumenttyp der main
eine String
Varargs anstelle eines String-Arrays sein. main
kann optional Ausnahmen auslösen, und der Parameter kann beliebig benannt werden, üblicherweise sind dies jedoch args
.
JavaFX-Einstiegspunkte
Ab Java 8 kann der java
Befehl auch eine JavaFX-Anwendung direkt starten. JavaFX ist im JavaFX- Tag dokumentiert, ein JavaFX-Einstiegspunkt muss jedoch Folgendes ausführen:
- Erweitern Sie
javafx.application.Application
- Seien Sie
public
und nichtabstract
- Nicht generisch oder verschachtelt sein
- Einen expliziten oder impliziten
public
No-Args-Konstruktor haben
Fehlerbehebung beim Befehl 'java'
In diesem Beispiel werden häufig auftretende Fehler bei der Verwendung des Befehls 'java' behandelt.
"Befehl nicht gefunden"
Wenn Sie eine Fehlermeldung erhalten, wie:
java: command not found
Wenn Sie versuchen, den java
Befehl auszuführen, bedeutet dies, dass sich im Befehlssuchpfad der Shell kein java
Befehl befindet. Die Ursache könnte sein:
- Sie haben überhaupt keine Java JRE oder JDK installiert,
- Sie haben die Umgebungsvariable
PATH
in Ihrer Shell-Initialisierungsdatei nicht (richtig) aktualisiert, oder - Sie haben die entsprechende Initialisierungsdatei in der aktuellen Shell nicht "beschafft".
Informationen zu den erforderlichen Schritten finden Sie unter "Java installieren" .
"Hauptklasse konnte nicht gefunden oder geladen werden"
Diese Fehlermeldung wird vom Befehl java
ausgegeben, wenn die angegebene Einstiegspunktklasse nicht gefunden / geladen werden konnte. Im Allgemeinen gibt es drei Gründe, warum dies passieren kann:
- Sie haben eine Einstiegspunktklasse angegeben, die nicht vorhanden ist.
- Die Klasse ist vorhanden, aber Sie haben sie falsch angegeben.
- Die Klasse ist vorhanden und Sie haben sie richtig angegeben. Java kann sie jedoch nicht finden, da der Klassenpfad falsch ist.
Hier ist ein Verfahren zur Diagnose und Lösung des Problems:
Finden Sie den vollständigen Namen der Einstiegspunktklasse heraus.
- Wenn Sie über Quellcode für eine Klasse verfügen, besteht der vollständige Name aus dem Paketnamen und dem einfachen Klassennamen. Die Instanz der "Main" -Klasse wird im Paket "com.example.myapp" deklariert. Der vollständige Name lautet "com.example.myapp.Main".
- Wenn Sie eine kompilierte Klassendatei haben, können Sie den Klassennamen finden, indem Sie
javap
daraufjavap
. - Wenn sich die Klassendatei in einem Verzeichnis befindet, können Sie den vollständigen Klassennamen aus den Verzeichnisnamen ableiten.
- Wenn sich die Klassendatei in einer JAR- oder ZIP-Datei befindet, können Sie den vollständigen Klassennamen aus dem Dateipfad in der JAR- oder ZIP-Datei ableiten.
Sehen Sie sich die Fehlermeldung des
java
Befehls an. Die Nachricht sollte mit dem vollständigen Klassennamen enden, denjava
verwendet.- Stellen Sie sicher, dass er genau mit dem vollständigen Klassennamen für die Einstiegsklasse übereinstimmt.
- Es sollte nicht mit ".java" oder ".class" enden.
- Es sollte keine Schrägstriche oder andere Zeichen enthalten, die in einem Java-Bezeichner nicht zulässig sind 1 .
- Das Gehäuse des Namens sollte genau mit dem vollständigen Klassennamen übereinstimmen.
Wenn Sie den richtigen Klassennamen verwenden, stellen Sie sicher, dass sich die Klasse tatsächlich im Klassenpfad befindet:
- Ermitteln Sie den Pfadnamen, dem der Klassenname zugeordnet ist. Siehe Klassennamen zu Pfadnamen zuordnen
- Ermitteln Sie, was der Klassenpfad ist. Sehen Sie sich dieses Beispiel an: Verschiedene Möglichkeiten, den Klassenpfad anzugeben
- Sehen Sie sich die JAR- und ZIP-Dateien im Klassenpfad an, um zu sehen, ob sie eine Klasse mit dem erforderlichen Pfadnamen enthalten.
- Sehen Sie sich jedes Verzeichnis an, um zu sehen, ob der Pfadname in eine Datei innerhalb des Verzeichnisses aufgelöst wird.
Wenn der Klassenpfad von Hand nicht gefunden wurde, konnten Sie die Optionen -Xdiag
und -XshowSettings
hinzufügen. Ersteres listet alle geladenen Klassen auf, und letzteres gibt Einstellungen aus, die den effektiven Klassenpfad für die JVM enthalten.
Schließlich gibt es einige dunkle Ursachen für dieses Problem:
- Eine ausführbare JAR-Datei mit einem Hauptklassenattribut, das eine nicht vorhandene
Main-Class
angibt. - Eine ausführbare JAR-Datei mit einem falschen
Class-Path
Attribut. - Wenn Sie vermasseln 2 die Optionen vor dem Klassennamen, die
java
versucht Befehl kann eine von ihnen als Klassennamen zu interpretieren. - Wenn jemand Java-Stilregeln ignoriert und Paket- oder Klassenbezeichner verwendet hat, die sich nur in Groß- und Kleinschreibung unterscheiden, und Sie auf einer Plattform ausgeführt werden, die Groß- / Kleinschreibung in Dateinamen als nicht signifikant behandelt.
- Probleme mit Homoglyphen in Klassennamen im Code oder in der Befehlszeile.
"Hauptmethode in Klasse <Name> nicht gefunden"
Dieses Problem tritt auf, wenn der java
Befehl die von Ihnen benannte Klasse finden und laden kann, aber keine Einstiegspunktmethode finden kann.
Es gibt drei mögliche Erklärungen:
- Wenn Sie versuchen, eine ausführbare JAR-Datei auszuführen, hat das JAR-Manifest ein falsches "Main-Class" -Attribut, das eine Klasse angibt, die keine gültige Einstiegspunktklasse ist.
- Sie haben dem
java
Befehl eine Klasse mitgeteilt, die keine Einstiegspunktklasse ist. - Die Einstiegspunktklasse ist falsch. Weitere Informationen finden Sie unter Einstiegspunktklassen .
Andere Ressourcen
- Was bedeutet "Konnte Hauptklasse nicht finden oder laden"?
- http://docs.oracle.com/javase/tutorial/getStarted/problems/index.html
1 - Ab Java 8 ordnet der java
Befehl hilfreich ein Dateinamen-Trennzeichen ("/" oder "") einem Punkt (".") Zu. Dieses Verhalten ist jedoch nicht in den Handbuchseiten dokumentiert.
2 - Ein wirklich verdeckter Fall liegt vor, wenn Sie einen Befehl aus einem formatierten Dokument kopieren und einfügen, wenn der Texteditor einen "langen Bindestrich" anstelle eines normalen Bindestrichs verwendet hat.
Ausführen einer Java-Anwendung mit Bibliotheksabhängigkeiten
Dies ist eine Fortsetzung der Beispiele "Hauptklasse" und "ausführbare JAR" .
Typische Java-Anwendungen bestehen aus einem anwendungsspezifischen Code und verschiedenen wiederverwendbaren Bibliothekscodes, die Sie implementiert haben oder von Dritten implementiert wurden. Letztere werden im Allgemeinen als Bibliotheksabhängigkeiten bezeichnet und werden normalerweise als JAR-Dateien verpackt.
Java ist eine dynamisch gebundene Sprache. Wenn Sie eine Java-Anwendung mit Bibliotheksabhängigkeiten ausführen, muss die JVM wissen, wo sich die Abhängigkeiten befinden, damit Klassen nach Bedarf geladen werden können. Im Großen und Ganzen gibt es zwei Möglichkeiten, damit umzugehen:
Die Anwendung und ihre Abhängigkeiten können in eine einzige JAR-Datei gepackt werden, die alle erforderlichen Klassen und Ressourcen enthält.
Der JVM kann über den Laufzeitklassenpfad mitgeteilt werden, wo die abhängigen JAR-Dateien zu finden sind.
Für eine ausführbare JAR-Datei wird der Laufzeitklassenpfad durch das Manifestattribut "Class-Path" angegeben. (Anmerkung der Redaktion: Dies sollte in einem eigenen Thema im jar
Befehl beschrieben werden.) Andernfalls muss der Klassenpfad der Laufzeit mithilfe der Option -cp
oder der Umgebungsvariable CLASSPATH
werden.
Angenommen, wir haben eine Java-Anwendung in der Datei "myApp.jar", deren Einstiegspunktklasse com.example.MyApp
. Angenommen, die Anwendung hängt von den Bibliotheks-JAR-Dateien "lib / library1.jar" und "lib / library2.jar" ab. Wir könnten die Anwendung mit dem java
Befehl wie folgt in einer Befehlszeile starten:
$ # Alternative 1 (preferred)
$ java -cp myApp.jar:lib/library1.jar:lib/library2.jar com.example.MyApp
$ # Alternative 2
$ export CLASSPATH=myApp.jar:lib/library1.jar:lib/library2.jar
$ java com.example.MyApp
(Unter Windows würden Sie ;
anstelle von :
als Klassenpfad-Trennzeichen verwenden und die (lokale) CLASSPATH
Variable mit set
statt mit export
set
.)
Ein Java-Entwickler wäre damit zwar vertraut, aber nicht "benutzerfreundlich". Daher ist es üblich, ein einfaches Shellskript (oder eine Windows-Batchdatei) zu schreiben, um die Details auszublenden, über die der Benutzer nicht informiert sein muss. Wenn Sie beispielsweise das folgende Shell-Skript in eine Datei namens "myApp" ablegen, diese ausführbar machen und in einem Verzeichnis im Befehlssuchpfad ablegen:
#!/bin/bash
# The 'myApp' wrapper script
export DIR=/usr/libexec/myApp
export CLASSPATH=$DIR/myApp.jar:$DIR/lib/library1.jar:$DIR/lib/library2.jar
java com.example.MyApp
dann könntest du es wie folgt ausführen:
$ myApp arg1 arg2 ...
Alle Argumente in der Befehlszeile werden über die Erweiterung "$@"
an die Java-Anwendung übergeben. (Mit einer Windows-Batchdatei können Sie etwas ähnliches machen, die Syntax ist jedoch unterschiedlich.)
Leerzeichen und andere Sonderzeichen in Argumenten
Zunächst ist das Problem der Behandlung von Leerzeichen in Argumenten NICHT ein Java-Problem. Es ist eher ein Problem, das von der Befehlsshell behandelt werden muss, die Sie beim Ausführen eines Java-Programms verwenden.
Nehmen wir als Beispiel an, wir haben das folgende einfache Programm, das die Größe einer Datei ausgibt:
import java.io.File;
public class PrintFileSizes {
public static void main(String[] args) {
for (String name: args) {
File file = new File(name);
System.out.println("Size of '" + file + "' is " + file.size());
}
}
}
Angenommen, wir möchten die Größe einer Datei drucken, deren Pfadname Leerzeichen enthält. zB /home/steve/Test File.txt
. Wenn wir den Befehl so ausführen:
$ java PrintFileSizes /home/steve/Test File.txt
Die Shell weiß nicht, dass /home/steve/Test File.txt
tatsächlich ein Pfadname ist. Stattdessen werden zwei verschiedene Argumente an die Java-Anwendung übergeben, die versucht, ihre jeweilige Dateigröße zu ermitteln, und schlagen fehl, da Dateien mit diesen Pfaden (wahrscheinlich) nicht vorhanden sind.
Lösungen mit einer POSIX-Shell
POSIX-Shells umfassen sh
sowie Derivate wie bash
und ksh
. Wenn Sie eine dieser Shells verwenden, können Sie das Problem lösen, indem Sie das Argument zitieren .
$ java PrintFileSizes "/home/steve/Test File.txt"
Die Anführungszeichen um den Pfadnamen geben der Shell an, dass sie als einzelnes Argument übergeben werden sollte. Die Anführungszeichen werden in diesem Fall entfernt. Es gibt mehrere Möglichkeiten, dies zu tun:
$ java PrintFileSizes '/home/steve/Test File.txt'
Einfache (gerade) Anführungszeichen werden wie Anführungszeichen behandelt, mit der Ausnahme, dass sie auch verschiedene Erweiterungen innerhalb des Arguments unterdrücken.
$ java PrintFileSizes /home/steve/Test\ File.txt
Ein Backslash entkommt dem folgenden Leerzeichen und bewirkt, dass es nicht als Argumenttrennzeichen interpretiert wird.
Eine umfassendere Dokumentation, einschließlich Beschreibungen zum Umgang mit anderen Sonderzeichen in Argumenten, finden Sie im Zitierthema der Bash- Dokumentation.
Lösung für Windows
Das grundlegende Problem für Windows ist, dass auf Betriebssystemebene die Argumente als einzelne Zeichenfolge ( Quelle ) an einen untergeordneten Prozess übergeben werden. Dies bedeutet, dass die endgültige Verantwortung für das Parsen (oder das erneute Parsen) der Befehlszeile entweder dem Programm oder dessen Laufzeitbibliotheken obliegt. Es gibt viele Unstimmigkeiten.
Im Java-Fall, um es kurz zu machen:
Sie können ein Argument in einem
java
Befehl in doppelte Anführungszeichen setzen, um Argumente mit Leerzeichen zu übergeben.Anscheinend
java
derjava
Befehl selbst die Befehlszeichenfolge, und er erhält mehr oder weniger RechtWenn Sie jedoch versuchen, dies mit
SET
und der Variablensubstitution in einer Batchdatei zu kombinieren, wird es sehr kompliziert, ob doppelte Anführungszeichen entfernt werden.Die Shell
cmd.exe
verfügt offenbar über andere Escape-Mechanismen. zB Verdoppelung doppelte Anführungszeichen, und mit^
entkommt.
Weitere Informationen finden Sie in der Batch-File- Dokumentation.
Java-Optionen
Der java
Befehl unterstützt eine Vielzahl von Optionen:
Alle Optionen beginnen mit einem einzelnen Bindestrich oder Minuszeichen (
-
): Die GNU / Linux-Konvention der Verwendung von--
for "long" -Optionen wird nicht unterstützt.Optionen müssen vor dem Argument
<classname>
oder-jar <jarfile>
, damit sie erkannt werden. Alle nachfolgenden Argumente werden als Argumente behandelt, die an die ausgeführte Java-App übergeben werden.Optionen, die nicht mit
-X
oder-XX
sind Standardoptionen. Sie können sich auf alle Java-Implementierungen 1 verlassen , um jede Standardoption zu unterstützen.Optionen, die mit
-X
sind keine Standardoptionen und können von einer Java-Version zur nächsten zurückgezogen werden.Optionen, die mit
-XX
sind erweiterte Optionen und können auch zurückgezogen werden.
Systemeigenschaften mit -D
Die Option -D<property>=<value>
wird verwendet, um eine Eigenschaft im Eigenschaftenobjekt des Systems Properties
. Dieser Parameter kann wiederholt werden, um andere Eigenschaften festzulegen.
Optionen für Speicher, Stack und Garbage Collector
Die wichtigsten Optionen zum Steuern der Heap- und Stackgrößen sind in Einstellen der Heap-, PermGen- und Stackgrößen dokumentiert. (Anmerkung der Redaktion: Garbage Collector-Optionen sollten in demselben Thema beschrieben werden.)
Assertions aktivieren und deaktivieren
Die -ea
und -da
Optionen bzw. aktivieren und Java deaktivieren assert
Überprüfung:
- Alle Assertionsprüfungen sind standardmäßig deaktiviert.
- Die Option
-ea
ermöglicht die Überprüfung aller Zusicherungen - Die
-ea:<packagename>...
ermöglicht die Überprüfung von Zusicherungen in einem Paket und allen Unterpaketen . - Die
-ea:<classname>...
ermöglicht die Überprüfung von Assertions in einer Klasse. - Die Option
-da
deaktiviert die Prüfung aller Zusicherungen - Die
-da:<packagename>...
deaktiviert die Prüfung von Zusicherungen in einem Paket und allen untergeordneten Paketen . - Die
-da:<classname>...
deaktiviert die Prüfung von Assertions in einer Klasse. - Die Option
-esa
ermöglicht die Überprüfung aller-esa
. - Die Option
-dsa
deaktiviert die Prüfung für alle-dsa
.
Die Optionen können kombiniert werden. Zum Beispiel.
$ # Enable all assertion checking in non-system classes
$ java -ea -dsa MyApp
$ # Enable assertions for all classes in a package except for one.
$ java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat MyApp
Beachten Sie, dass die Aktivierung der Assertionsprüfung das Verhalten einer Java-Programmierung ändern kann.
- Es ist wahrscheinlich, dass die Anwendung im Allgemeinen langsamer wird.
- Dies kann dazu führen, dass bestimmte Methoden länger dauern, was das Timing von Threads in einer Multithread-Anwendung ändern kann.
- Es kann zufällige Ereignisse vor den Beziehungen einleiten, die dazu führen können, dass Anomalien des Gedächtnisses verschwinden.
- Eine falsch implementierte
assert
Anweisung kann unerwünschte Nebenwirkungen haben.
Auswahl des VM-Typs
Mit den Optionen -client
und -server
können Sie zwischen zwei verschiedenen Formen der HotSpot-VM wählen:
- Das "Client" -Formular ist auf Benutzeranwendungen abgestimmt und ermöglicht einen schnelleren Start.
- Das "Server" -Formular ist auf lang laufende Anwendungen abgestimmt. Während des Aufwärmens der JVM dauert die Erfassungsstatistik länger, wodurch der JIT-Compiler die Optimierung des nativen Codes verbessern kann.
Standardmäßig wird die JVM, sofern möglich, je nach den Fähigkeiten der Plattform im 64-Bit-Modus ausgeführt. Mit den Optionen -d32
und -d64
können Sie den Modus explizit auswählen.
1 - Überprüfen Sie das offizielle Handbuch für den java
Befehl. Manchmal wird eine Standardoption als "Änderungen vorbehalten" bezeichnet.