Ich denke, die meiste Zeit benutze ich IDE für die Java-Programmierung. Selbst wenn Sie mit dem Erlernen der Java-Programmierung beginnen, ist dies häufig bei der Vorbereitung der IDE erforderlich. Wenn Anfänger jedoch anfangen, aus der Java-Programmierung in der IDE zu lernen, können sie die von der IDE unterstützten Teile nicht genau verstehen oder nur abhängig von der IDE arbeiten, selbst wenn sie Code in die IDE schreiben können. Ich kann nicht aus dem Staat wachsen. Dieser Artikel richtet sich an Anfänger, um ihr Verständnis zu vertiefen, indem sie einfache Java-Programme mit CLI ohne Verwendung von IDE ausführen. Das detaillierte Lesen oder Schreiben des Programms wird nicht erwähnt. Für Anfänger mögen schwierige Wörter und Konzepte auf dem Weg erscheinen, aber es ist nicht notwendig, sie sofort zu verstehen. Bitte lesen Sie sie durch und verstehen Sie sie nach und nach.
Es wird das Betriebssystem sein, an dem Sie gerade arbeiten, und die Version von Java, die Sie verwenden werden. In diesem Artikel arbeite ich an CentOS, aber wenn Sie vagrant nicht installieren können, können Sie auf Mac arbeiten. Wenn Sie den UNIX-Befehl ersetzen, können Sie an der Windows-Eingabeaufforderung arbeiten (nicht überprüft). ..
OS
Verwenden Sie diese BOX, um eine VM mit Vagrant auf VirtualBox zu starten und darin zu arbeiten.
$ cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
Java
Installieren Sie This OpenJDK mit yum und verwenden Sie es.
$ java -version
java 10.0.2 2018-07-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.2+13)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode)
$ javac -version
javac 10.0.2
Java-Programme werden normalerweise vor der Ausführung mit einem Javac-Tool von ".java" bis ".class" Bytecode (auch Zwischencode genannt) kompiliert. Wenn das Programm ausgeführt wird, wird der Bytecode in der JVM auf eine Interpreter-Weise ausgeführt, oder der JIT-Compiler kompiliert ihn erneut in Maschinencode und führt ihn aus. Der JIT-Compiler ist eine der Komponenten von JRE (Java Runtime Environment) und ein Mechanismus zur Optimierung des Maschinencodes von Programmmethoden und zur Verbesserung der Leistung.
Von hier aus kompilieren und führen Sie Java-Programme aus und erstellen Archive mit der CLI.
Schreiben Sie zunächst ein Programm, das "Hallo Welt" ausgibt, und führen Sie es aus. Die auszuführende Programmdatei lautet wie folgt. Bereiten Sie sie daher mit vi usw. vor.
App.java
class App {
public static void main(String[] args) {
System.out.println("Hello world.");
}
}
Kompilieren Sie dies mit Javac.
$ ls
App.java
$ javac App.java
$ ls
App.class App.java
Sie können sehen, dass die .class-Datei generiert wurde. Führen Sie es dann in Java aus. Beachten Sie, dass das Argument der Klassenname und nicht der Dateiname ist.
$ java App
Hello world.
Es war einfach, aber ich habe das Programm kompiliert und ausgeführt. Bisher gibt es kein Problem.
Versuchen Sie, Argumente auszuführen, wenn Sie das Programm ausführen. Nehmen Sie die folgenden Änderungen an der vorherigen Programmdatei vor.
App.java
class App {
public static void main(String[] args) {
for (String arg: args) {
System.out.println(String.format("Hello %s.", arg));
}
}
}
Kompilieren und ausführen. Lassen Sie uns im Gegensatz zu früher zur Laufzeit ein Argument übergeben.
$ java App Alice Bob Carol
Hello Alice.
Hello Bob.
Hello Carol.
Sie können sehen, dass das Argument empfangen wurde.
Versuchen Sie, auf andere Klassen in Ihrem Programm zuzugreifen. Erstellen Sie zunächst eine Human-Klasse, die Menschen als eine andere Klasse in einer anderen Datei darstellt.
Human.java
class Human {
String name;
Human(String name) {
this.name = name;
}
void introduceMyself() {
System.out.println(String.format("My name is %s.", this.name));
}
}
Instanziieren Sie die Human-Klasse in der Hauptmethode der App-Klasse.
App.java
class App {
public static void main(String[] args) {
for (String arg: args) {
Human human = new Human(arg);
human.introduceMyself();
}
}
}
Lassen Sie es uns kompilieren.
$ ls
App.java Human.java
$ javac App.java
$ ls
App.class App.java Human.class Human.java
Sie können sehen, dass Human zusammen mit der Kompilierung der App kompiliert wurde.
$ java App Alice Bob Carol
My name is Alice.
My name is Bob.
My name is Carol.
Ich habe so viele menschliche Instanzen wie die Anzahl der Argumente erstellt und bestätigt, dass die Methode ausgeführt wurde.
Geben Sie ihm einen Paketnamen und versuchen Sie, ihn als Programm in einem separaten Paket zu kompilieren. Geben Sie der Klasse Human zunächst einen Paketnamen. Da auf diese Klasse von einem anderen Paket aus zugegriffen wird, habe ich jeden Modifikator korrekt hinzugefügt.
Human.java
package jp.co.sample.lib;
public class Human {
private String name;
public Human(String name) {
this.name = name;
}
public void introduceMyself() {
System.out.println(String.format("My name is %s.", this.name));
}
}
Geben Sie als Nächstes für die App-Klasse den Paketnamen an und beschreiben Sie den Import für den Zugriff auf die Human-Klasse.
App.java
package jp.co.sample;
import jp.co.sample.lib.Human;
class App {
public static void main(String[] args) {
for (String arg: args) {
Human human = new Human(arg);
human.introduceMyself();
}
}
}
Der Paketname wurde zugewiesen, kann jedoch nicht so kompiliert werden, wie er ist. In Java müssen die Dateien in derselben Verzeichnisstruktur wie der Paketname angeordnet werden. Erstellen Sie also ein Verzeichnis wie unten gezeigt und verschieben Sie die Dateien.
$ tree
.
└── jp
└── co
└── sample
├── App.java
└── lib
└── Human.java
4 directories, 2 files
Kompilieren Sie die Datei nach dem Verschieben und führen Sie sie aus.
$ javac jp/co/sample/App.java
$ tree
.
└── jp
└── co
└── sample
├── App.class
├── App.java
└── lib
├── Human.class
└── Human.java
4 directories, 4 files
$ java jp.co.sample.App Alice Bob Carol
My name is Alice.
My name is Bob.
My name is Carol.
Es wurde bestätigt, dass die .class-Datei auf derselben Ebene wie jede .java-Datei erstellt wurde und das Programm ausgeführt werden konnte.
Kombinieren Sie die erstellten ".class" -Dateien zu ".jar" und erstellen Sie ein Archiv. Die .java-Datei ist nicht in .jar enthalten. Trennen Sie sie daher als src-Verzeichnis.
$ tree
.
└── src
└── jp
└── co
└── sample
├── App.java
└── lib
└── Human.java
5 directories, 2 files
Kompilieren Sie die .class
-Datei und geben Sie sie in das Klassenverzeichnis aus. Wenn Sie an einem anderen Speicherort als dem Verzeichnis src für den Paketursprung ausgeführt werden möchten, müssen Sie den Paketursprung mit der Option -sourcepath
angeben.
$ javac -sourcepath src -d classes src/jp/co/sample/App.java
$ tree
.
├── classes
│ └── jp
│ └── co
│ └── sample
│ ├── App.class
│ └── lib
│ └── Human.class
└── src
└── jp
└── co
└── sample
├── App.java
└── lib
└── Human.java
10 directories, 4 files
Sie können sehen, dass das Klassenverzeichnis erstellt wurde und die ".class" -Dateien darunter mit derselben Verzeichnisstruktur wie das Paket erstellt wurden. Übrigens, wenn Sie zur Laufzeit an einem anderen Ort als dem Paketursprung ausführen möchten, müssen Sie den Paketursprung mit der Option "-classpath" angeben.
$ java -classpath classes jp.co.sample.App Alice Bob Carol
My name is Alice.
My name is Bob.
My name is Carol.
Als nächstes muss die MANIFEST-Datei ".jar" erstellen. Erstellen Sie daher die folgende Datei. Der Name der Klasse mit der Hauptmethode wird hier beschrieben, einschließlich des Paketnamens. Vergessen Sie nicht, dass eine leere Zeile in der letzten Zeile nicht als MANIFEST-Datei erkannt wird.
manifest.mf
Main-Class: jp.co.sample.App
Erstellen Sie nach dem Vorbereiten der MANIFEST-Datei eine .jar-Datei mit jar.
$ jar cvfm sample.jar manifest.mf -C classes .
Manifest hinzugefügt
jp/Wird hinzugefügt(Eingeben=0)(aus=0)(0%Gelagert)
jp/co/Wird hinzugefügt(Eingeben=0)(aus=0)(0%Gelagert)
jp/co/sample/Wird hinzugefügt(Eingeben=0)(aus=0)(0%Gelagert)
jp/co/sample/App.Klasse wird hinzugefügt(Eingeben=469)(aus=343)(26%Schrumpfte)
jp/co/sample/lib/Wird hinzugefügt(Eingeben=0)(aus=0)(0%Gelagert)
jp/co/sample/lib/Human.Klasse wird hinzugefügt(Eingeben=595)(aus=382)(35%Schrumpfte)
$ ls
classes manifest.mf sample.jar src
$ jar -tf sample.jar
META-INF/
META-INF/MANIFEST.MF
jp/
jp/co/
jp/co/sample/
jp/co/sample/App.class
jp/co/sample/lib/
jp/co/sample/lib/Human.class
Sie können sehen, dass die .jar-Datei die MANIFEST-Datei und die .class-Datei enthält. Lassen Sie uns abschließend die .jar-Datei ausführen.
$ java -jar sample.jar Alice Bob Carol
My name is Alice.
My name is Bob.
My name is Carol.
In diesem Artikel habe ich ein Programm geschrieben, es kompiliert und dann eine .jar
-Datei erstellt und ausgeführt. Möglicherweise haben Sie das Gefühl, dass der Arbeitsinhalt zwischen dem Arbeiten in der IDE und dem Drücken von Befehlen in der CLI zum Kompilieren und Ausführen sehr unterschiedlich ist. Während Sie in einer IDE mit einer Benutzeroberfläche intuitiv arbeiten können, müssen Sie jeden Befehl in der CLI verstehen und ausführen. Ich denke, dass das Verständnis des Inhalts dieses Artikels Ihnen auch hilft, die Arbeit in IDE zu verstehen.
OpenJDK enthält ein Tool, mit dem die kompilierte ".class" -Datei umgekehrt zusammengestellt werden kann. Sie können der detaillierten Anweisung des Programms folgen. Wenn Sie es sich leisten können, sollten Sie einen Blick darauf werfen.
$ javap -v -classpath classes jp.co.sample.App
Classfile /home/vagrant/java_test/classes/jp/co/sample/App.class
Last modified 2019/04/30; size 469 bytes
MD5 checksum 7ad6f96dd09200ac12a4c48cadb71ea8
Compiled from "App.java"
class jp.co.sample.App
minor version: 0
major version: 54
flags: (0x0020) ACC_SUPER
this_class: #5 // jp/co/sample/App
super_class: #6 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
#1 = Methodref #6.#17 // java/lang/Object."<init>":()V
#2 = Class #18 // jp/co/sample/lib/Human
#3 = Methodref #2.#19 // jp/co/sample/lib/Human."<init>":(Ljava/lang/String;)V
#4 = Methodref #2.#20 // jp/co/sample/lib/Human.introduceMyself:()V
#5 = Class #21 // jp/co/sample/App
#6 = Class #22 // java/lang/Object
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 main
#12 = Utf8 ([Ljava/lang/String;)V
#13 = Utf8 StackMapTable
#14 = Class #23 // "[Ljava/lang/String;"
#15 = Utf8 SourceFile
#16 = Utf8 App.java
#17 = NameAndType #7:#8 // "<init>":()V
#18 = Utf8 jp/co/sample/lib/Human
#19 = NameAndType #7:#24 // "<init>":(Ljava/lang/String;)V
#20 = NameAndType #25:#8 // introduceMyself:()V
#21 = Utf8 jp/co/sample/App
#22 = Utf8 java/lang/Object
#23 = Utf8 [Ljava/lang/String;
#24 = Utf8 (Ljava/lang/String;)V
#25 = Utf8 introduceMyself
{
jp.co.sample.App();
descriptor: ()V
flags: (0x0000)
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 5: 0
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=6, args_size=1
0: aload_0
1: astore_1
2: aload_1
3: arraylength
4: istore_2
5: iconst_0
6: istore_3
7: iload_3
8: iload_2
9: if_icmpge 39
12: aload_1
13: iload_3
14: aaload
15: astore 4
17: new #2 // class jp/co/sample/lib/Human
20: dup
21: aload 4
23: invokespecial #3 // Method jp/co/sample/lib/Human."<init>":(Ljava/lang/String;)V
26: astore 5
28: aload 5
30: invokevirtual #4 // Method jp/co/sample/lib/Human.introduceMyself:()V
33: iinc 3, 1
36: goto 7
39: return
LineNumberTable:
line 7: 0
line 8: 17
line 9: 28
line 7: 33
line 11: 39
StackMapTable: number_of_entries = 2
frame_type = 254 /* append */
offset_delta = 7
locals = [ class "[Ljava/lang/String;", int, int ]
frame_type = 248 /* chop */
offset_delta = 31
}
SourceFile: "App.java"
Recommended Posts