
srk
Erstens bedauere ich, dass dies eine sehr grundlegende Frage ist, und ich befürworte, dass ich immer noch ein Code-Affe bin. Ich wurde in einem Interview gebeten, System.out.println(); Ich habe es auf folgende Weise erklärt
//this class belongs to java.lang package
class System{
public static PrintStream out;
}
//this class belongs to java.io package
class PrintStream{
public void println..
}
Ich habe erklärt, dass System.out gültig ist, da wir auf diese Weise auf statische Variablen in Java zugreifen und out ein Objekt von PrintStream ist und wir daher auf seine Methoden zugreifen können
System.out.pritnln();
Er bat mich, ein ähnliches Programm zu simulieren, das ich nachverfolgt habe, und es hat nicht funktioniert, da System.out null zurückgibt
Meine Frage ist, wo ist unser Objekt in Java instanziiert? Ist es ein vordefiniertes Objekt, wenn ich mich nicht irre. was soll die genaue Erklärung dafür sein.
Was sollten wir technisch nennen? Ist out eine Variable vom Typ PrintStream oder sollte man es als Objekt vom Typ PrintStream sagen?
System.out wird auf initialisiert null
wenn die Klasse instanziiert wird. Dies wird durch die festgelegt nullPrintStream()
Methode ein System.java
die gerade zurückkehrt null
.
Wenn die JVM initialisiert wurde, ruft sie die initializeSystemClass()
Methode. Diese Methode ruft die auf native
Methode setOut0()
die setzt die out
Variable auf den entsprechenden Wert.
Dies mag seltsam erscheinen, ist aber aus folgenden Gründen eine notwendige Operation:
out
kann nicht statisch auf den Wert gesetzt werden, weil System
muss eine der ersten geladenen Klassen sein (vorher PrintStream
).
out
muss sein final
sodass sein Wert nicht direkt von einem Benutzer überschrieben werden kann.
- Seit
out
nicht statisch festgelegt werden kann und endgültig ist, müssen wir die Semantik der Sprache mit a überschreiben native
Methode, setOut0()
.
Ich hoffe, das hilft Ihrem Verständnis.

Oscar López
System.out
ist ein normales statisches Attribut, es wurde von der JVM durch die gesetzt initializeSystemClass()
-Methode während der JVM-Initialisierung. Du kannst sogar Veränderung es (obwohl es nicht empfohlen wird), indem Sie einfach anrufen System.setOut(printOutStream);
wo printOutStream
ist der Stream, den Sie als Standardausgabe verwenden möchten.
Hier ist ein nettes Artikel detailliert, wie System.out.println() funktioniert.
System.out wird von der JVM bereitgestellt. Wenn Ihre Hauptmethode aufgerufen wird, ist System.out geöffnet und einsatzbereit.
Sehen http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#out
In den Oracle Java-Laufzeitbibliotheken wird es nativ mithilfe von instanziiert registerNatives()
native Methode, die aufgerufen wird (über a static
Initialisierer) beim Laden der System
Klasse. Dies ist jedoch ein Implementierungsdetail.
Sie können auch einstellen System.out
direkt verwenden System.setOut()
.
Out in System.out.pritln ist ein statisches Feld (Objekt) von PrintWriter in der Systemklasse und println ist eine Methode von PrintWriter.
Referenzsystem : http://docs.oracle.com/javase/6/docs/api/java/lang/System.html
PrintWriter : http://docs.oracle.com/javase/6/docs/api/java/io/PrintWriter.html

Benutzer3282701
Es besteht keine Notwendigkeit, sich für Netz und Dokumentation zu entscheiden. Wir können einfach sagen javap java.lang.System Dies gibt Ihnen eine Liste aller statischen Felder, Methodenprototypen, die zur Systemklasse gehören. Wir können Details zu jeder Java-Klasse mit Javap abrufen, vorausgesetzt, Sie wissen, dass ihr Paket und ihr Klassenname out ein öffentliches statisches Objekt von PrintStream ist, das in der Systemklasse definiert ist.

Mohit Tyagi
Wenn die Systemklasse initialisiert wird, ruft sie ihre auf initializeSystemClass()
Methode, hier ist der Code:
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
In diesem Code setOut0()
ist eine native Funktion, die in System.c implementiert ist:
JNIEXPORT void JNICALL
Java_java_lang_System_setOut0(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);
}
Dies ist ein Standard-JNI-Code, der System.out auf das übergebene Argument setzt. Diese Methode ruft die native Methode setOut0() auf, die die out-Variable auf den entsprechenden Wert setzt.
System.out
final ist, bedeutet dies, dass sie in initializeSystemClass() nicht auf etwas anderes gesetzt werden kann, aber mit nativem Code ist es möglich, eine finale Variable zu ändern.
10143500cookie-checkaus in System.out.println()yes
Was meinst du mit “System.out gibt null zurück”?
– Oliver Charlesworth
26. Februar 2012 um 16:40 Uhr
Ich habe ein analoges Programm wie class A{ static B out} erstellt; class B{ } Ich habe versucht, System.out.println(A.out) zu drucken; was null zurückgibt.
– srk
26. Februar 2012 um 17:10 Uhr