Die meisten Websites im Internet sagen:
"Verwenden Sie den
javac
Befehl, um eine.java
Datei zu kompilieren . Führen Sie sie dann mit demjava
Befehl aus."
Aber heute habe ich versucht, ein Java-Programm ohne auszuführen, javac
und ich habe ein seltsames Ergebnis erzielt.
Hier ist der Inhalt einer Datei namens hello.java
:
public class Myclass {
public static void main(String[] args){
System.out.println("hello world");
}
}
Dann rannte ich:
$ javac hello.java
Was mir diesen Fehler gibt:
hello.java:1: error: class Myclass is public, should be declared in a file named Myclass.java
public class Myclass {
^
1 error
Aber wenn ich es ohne den javac
Befehl ausführe , wird es ohne Fehler ausgeführt.
$ java hello.java
hello world
Hat der java
Befehl auch das Programm zusammenstellen ? Wenn ja, warum brauchen wir den javac
Befehl?
Die Version meines Java ist:
openjdk version "12.0.2" 2019-07-16
OpenJDK Runtime Environment (build 12.0.2+10)
OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode)
Myclass.java
und kompilieren Sie ihn dann über die Befehlszeile wie folgtjavac Myclass.java
und führen Sie ihn dann so ausjava Myclass
.javac
immer noch zum Kompilieren verwendet, wenn Sie keinen Quellcode bereitstellen möchten oder wenn Sie mehr als eine einzelne Datei haben ( Dokumentation derjava
Option für die Quelldatei:javac
Kompiliert die Java-Quelle in JVM-spezifisch interpretierten Bytecode und derjava
Befehl lädt ihn in den ClassLoader der JVM.Antworten:
Um Ihren Code vor Java 11 auszuführen, müssen Sie ihn zuerst kompilieren und dann ausführen. Hier ist ein Beispiel:
Seit Java 11 können Sie immer noch
javac
+java
ausführen oderjava
selbst ausführen, um Ihren Code zu kompilieren und automatisch auszuführen. Beachten Sie, dass keine.class
Datei generiert wird. Hier ist ein Beispiel:Wenn Sie ausführen
java -help
, werden die verschiedenen zulässigen Verwendungen angezeigt. So sieht es auf meinem Computer aus. Der letzte ist der, auf den Sie gestoßen sind:java [options] <sourcefile> [args]
der "ein einzelnes Quelldateiprogramm ausführen" wird.AKTUALISIEREN:
Wie von @BillK hervorgehoben, fragte OP auch:
Der Grund, den wir brauchen,
javac
ist das Erstellen von.class
Dateien, damit Code wie heute erstellt, getestet, verteilt, ausgeführt, freigegeben usw. werden kann. Die Motivation für JEP 330 bestand darin, es für "frühe Phasen des Lernens von Java und beim Schreiben kleiner Hilfsprogramme" einfacher zu machen, ohne andere vorhandene Verwendungen zu ändern.quelle
1.
in1.8
neueren Versionen eingestellt)javac
.Wenn Sie Java 11 ausführen , gibt es eine neue Funktion, die die Ausführung von Dateien aus einer Quelle ermöglicht. Der Single-Source-Compiler ist in Bezug auf Klassennamen und Dateinamen promiskuitiver. Auf diese Weise können Sie zwar ausführen, aber nicht erfolgreich kompilieren.
Wenn Sie eine frühere Version von Java verwenden, wird Ihre aktuelle Datei hello.java aufgrund von Kompilierungsfehlern, insbesondere um den Klassennamen, nicht kompiliert. Das Aufrufen von java hello.java hat Ihren Code also auf keinen Fall kompiliert, da er nicht kompiliert wird.
Es ist sehr wahrscheinlich, dass Sie beim Ausführen des Java-Befehls zuvor kompilierten Code ausgeführt haben.
quelle
Um zu beantworten, warum dieser Fehler angegeben wird, muss der Klassenname für die Datei mit dem der Datei übereinstimmen
basename
.Sie haben zwei Möglichkeiten, damit dieser Code für den traditionellen Code funktioniert
javac
.java
Reihenfolge:Benennen Sie die Klasse in
public class Hello
oder umUmbenennen
hello.java
inmyclass.java
.Der
java
Interpreter für Java 11 legt diese Anforderung nicht fest. Die enthaltene Klassemain
kann einen beliebigen Namen haben, solange es sich um die erste Klasse in der Datei handelt. Dies sollte vor allem den Lernprozess für Anfänger erleichtern und "Java Scripting" mit dem Shebang ermöglichen ( Ref. ).quelle
Ja, aber nicht so, wie Sie es wahrscheinlich meinen.
Wenn Sie den
javac
Befehl verwenden, um eine Java-Datei in eine Klassendatei zu kompilieren, wird die Ausgabe als Bytecode bezeichnet. Bytecode ist der Maschinencode (native Anweisungen) für eine theoretische CPU, der auf der Java Virtual Machine-Spezifikation basiert.Diese virtuelle CPU-Spezifikation ist eine Art Durchschnitt der CPU-Typen, die zum Zeitpunkt der Erstellung der Spezifikation üblich waren. Aus diesem Grund liegt es in der Nähe vieler verschiedener CPU-Typen, was es einfacher macht, dieselben Java-Klassendateien auf mehreren CPU-Typen auszuführen.
Beim ersten Start von Java
java
las der Befehl die .class-Datei, interpretierte die Bytecode-Anweisungen nacheinander und ordnete sie dann der entsprechenden nativen Anweisung für die CPU zu, auf der sie tatsächlich ausgeführt wurde. Das hat funktioniert, war aber nicht besonders schnell. Um dies zu verbessern, wurde der Java Runtime eine JIT-Kompilierung (Just in Time) hinzugefügt.Mit JIT nimmt der
java
Befehl den Bytecode und kompiliert ihn erneut zu den nativen Anweisungen für die CPU, auf der er ausgeführt wird. Moderne Java-Laufzeiten beginnen in der Regel damit, den Bytecode zu interpretieren, während JIT im Hintergrund kompiliert wird, und wechseln zu den kompilierten nativen Anweisungen, wenn sie fertig sind. Außerdem wird die laufende Anwendung profiliert und der Bytecode erneut mit verschiedenen Optimierungen neu kompiliert, um die bestmögliche Leistung zu erzielen.EDIT (um die Down-Wähler zu beschwichtigen):
In Ihrem speziellen Fall (da Sie eine neuere JRE als Version 11 ausführen) wird der Code (mindestens) zweimal kompiliert
quelle
mixed-mode
die Ausgabe in der Version zeigt