Heim  >  Artikel  >  Java  >  Analyse des HelloWorld-Prinzips in Java

Analyse des HelloWorld-Prinzips in Java

黄舟
黄舟Original
2017-05-21 10:28:022098Durchsuche

Das erste Programm, das wir beim Erlernen von Java verwenden, ist „Hallo Welt“. Das Folgende ist eine Analyse der Prinzipien von Java HelloWorld anhand von Beispielcode. Interessierte Freunde können gemeinsam lernen

Das erste Programm für uns, um Java zu lernen, ist „Hallo Welt“

 public class HelloWorld {
   public static void main(String[] args) {
     System.out.println("hello world");
   }
}

Wie sieht das obige Programm aus? Wie wird „Hallo Welt“ auf dem Bildschirm ausgegeben? Dies sollte ursprünglich erklärt werden, nämlich das Prinzip von System.out.println("hello world").

Werfen wir zunächst einen Blick auf den Prozess von System.out.println. Schauen wir uns zunächst die Definition von out in System.java an. Der Quellcode lautet wie folgt:

public final class System {
   ... 
   public final static PrintStream out = null; 
   ...
 }

Daraus stellen wir fest, dass

(01) out System.javas statisch Variable.

(02) Und out ist ein PrintStream

-Objekt Es gibt viele überladene println()-Methoden in PrintStream.java.

OK, wir wissen, dass out ein PrintStream-Objekt ist. Sehen Sie sich als Nächstes an, wie es initialisiert wird und wie es mit der Bildschirmausgabe zusammenhängt.

Schauen wir uns zunächst die Methode initializeSystemClass() von System.java an.

1. Der Quellcode von initializeSystemClass() lautet wie folgt: Markieren Sie den Out-Teil in Rot

 private static void initializeSystemClass() {
   props = new Properties();
   initProperties(props); // initialized by the VM
   sun.misc.VM.saveAndRemoveProperties(props);
   lineSeparator = props.getProperty("line.separator");
   sun.misc.Version.init();
   FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
   FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
   FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
   setIn(new BufferedInputStream(fdIn));
   setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
   setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
   loadLibrary("zip");
   Terminator.setup();
   sun.misc.VM.initializeOSEnvironment();
   Thread current = Thread.currentThread();
   current.getThreadGroup().add(current);
   setJavaLangAccess();
   sun.misc.VM.booted();
 }
Wir müssen nur auf den roten Codeteil oben achten: das heißt,

FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
Diese beiden Sätze können in die folgenden Schritte unterteilt werden:

Schritt 1 FileDescriptor fd = FileDescriptor.out;

Schritt 2 FileOutputStream fdOut = new FileOutputStream( fd);

Schritt 3 BufferedOutputStream bufOut = new BufferedOutputStream(fdOut, 128);

Schritt 4 PrintStream ps = new PrintStream(bufout, true);

Schritt 5 setOut0 ( ps);

Erklärung:

(01) Schritt 1: Holen Sie sich das statische Element in FileDescriptor.java. Es handelt sich um ein FileDescriptor-Objekt, bei dem es sich tatsächlich um eine „Standardausgabe (Bildschirm)“ handelt. Identifikator.


Der Code für FileDescriptor.out in FileDescriptor.java lautet wie folgt:

 public final class FileDescriptor {
    private int fd;
   public static final FileDescriptor out = new FileDescriptor(1);
   private FileDescriptor(int fd) {
     this.fd = fd;
     useCount = new AtomicInteger();
   }
   ...
 }
(02) Erstellen Sie einen „Dateiausgabestream“, der der „Standardausgabe (Bildschirm)“ entspricht )".

(03) Erstellen Sie einen „gepufferten Ausgabestream“, der dem „Dateiausgabestream“ entspricht. Der Zweck besteht darin, dem „File Output Stream“ eine „Puffer“-Funktionalität hinzuzufügen.

(04) Erstellen Sie einen „Druckausgabestream“, der dem „gepufferten Ausgabestream“ entspricht. Der Zweck besteht darin, eine praktische

Schnittstelle für den „gepufferten Ausgabestrom“ bereitzustellen, z. B. print(), println(), printf();, damit die Ausgabe bequem gedruckt werden kann Und zwar schnell.

(05) Führen Sie setOut0(ps) aus;

Als nächstes analysieren Sie setOut0(ps) in Schritt 5. Überprüfen Sie die Deklaration von setOut0() in System.java wie folgt:

private static native void setOut0(PrintStream out);
Daraus stellen wir fest, dass setOut0() eine native Methode ist. Über openjdk können wir den entsprechenden Quellcode wie folgt finden:

 JNIEXPORT void JNICALL
 Java_java_lang_System_setOut(JNIEnv *env, jclass cla, jobject stream)
 {
   jfieldID fid =
     (*env)->GetStaticFieldID(env,cla,"out","Ljava/io/PrintStream;");
   if (fid == 0)
     return;
   (*env)->SetStaticObjectField(env,cla,fid,stream);
 }
Erklärung:

Dies ist eine JNI

Funktion, lassen Sie uns eine einfache Analyse davon durchführen .

(01) Funktionsname

JNIEXPORT void JNICALL Java_java_lang_System_setOut0(JNIEnv *env, jclass cla, jobject stream)
Dies ist die statische Registrierungsmethode von JNI. Java_java_lang_System_setOut0(JNIEnv *env, jclass cla, jobject stream) ist dasselbe wie setOut0(PrintStream) in System.java out); außerdem entspricht der Parameter stream dem Parameter out. Um es einfach auszudrücken: Wenn wir setOut0() aufrufen, rufen wir tatsächlich Java_java_lang_System_setOut0() auf.

(02) jfieldID fid = (*env)->GetStaticFieldID(env,cla,"out","Ljava/io/PrintStream;");

Was dieser Satz bewirkt? besteht darin, die jfieldID des statischen Mitglieds aus System.java abzurufen. „Ljava/io/PrintStream;“ bedeutet, dass out ein java.io.PrintStream-Objekt ist.

Der Zweck des Abrufens der jfieldID von out besteht darin, dass wir den Wert von out ändern müssen, indem wir „jfieldID von out“ ausführen.

(03) (*env)->SetStaticObjectField(env,cla,fid,stream);

Die Funktion dieses Satzes besteht darin, die entsprechende FID festzulegen (Fid ist die jfieldID von out) Der Wert des statischen Mitglieds ist stream.

stream ist der Parameter, den wir an Java_java_lang_System_setOut0() übergeben, welches der Parameter ist, der an setOut0 übergeben wird.

Zusammenfassung des oben Gesagten. Wir wissen, dass die Funktion von setOut0(PrintStream ps) darin besteht, ps auf die statische Out-Variable von System.java zu setzen.


Wie bereits erwähnt, ist FileDescriptor.out die Dateikennung der „Standardausgabe (Bildschirm)“ der Maschine. Wir können die Dateikennung im Allgemeinen als die durch FileDescriptor.out dargestellte „Standardausgabe“ verstehen.

Daher dienen die oben genannten 5 Schritte in initializeSystemClass() dazu, „FileDescriptor.out“ zu kapseln. Das gekapselte System.in verfügt sowohl über eine Pufferfunktion als auch über praktische Bedienschnittstellen wie print(), println() und printf().


Das obige ist der detaillierte Inhalt vonAnalyse des HelloWorld-Prinzips in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn