可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Firstly regrets if this is a very basic question and i promote that I'm still a code monkey.
I was asked in an interview to elucidate System.out.println();
I explained the following way
//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..
}
I've explained that System.out is valid since this is the way we access static variables in java, and out is an object of PrintStream and hence we can access its methods, In sum as
System.out.pritnln();
he asked me to simulate a similar kind of program,i traced and it did not work,since System.out is returning null
my question is where is out object instantiated in java ? Is it a predefined object if I'm not wrong. what should be the meticulous explanation for this.
Technically what should we call out? Is out a variable of type PrintStream type or should one say it as an object of type PrintStream ?
回答1:
System.out is initialized to null
when the class is instantiated. This is set by the nullPrintStream()
method in System.java
, which just returns null
.
When the JVM has initialized, it calls the initializeSystemClass()
method. This method calls the native
method setOut0()
which sets the out
variable to the appropriate value.
This may seem weird but it is a necessary operation for the following reasons:
out
cannot be set statically to the value because System
needs to be one of the first loaded classes (before PrintStream
).
out
must be final
so that its value cannot be directly overridden by a user.
- Since
out
cannot be set statically, and is final, we must override the semantics of the language using a native
method, setOut0()
.
I hope that helps your understanding.
回答2:
System.out
is a normal static attribute, it was set by the JVM through the initializeSystemClass()
method during JVM initialization. You can even change it (although it's not recommended) by simply calling System.setOut(printOutStream);
, where printOutStream
is the stream you want to use as standard output.
Here's a nice article detailing how does System.out.println() work.
回答3:
System.out.println()-
With that in mind, let’s break this down, starting with the dot operator. In Java, the dot operator can only be used to call methods and variables so we know that ‘out’ must be either a method or a variable. Now, how do we categorize ‘out’? Well, ‘out’ could not possibly be a method because of the fact that there are no parentheses – the ‘( )’ – after ‘out’, which means that out is clearly not a method that is being invoked. And, ‘out’ does not accept any arguments because only methods accept arguments – you will never see something like “System.out(2,3).println”. This means ‘out’ must be a variable.
‘out’ is being called with the ‘System’ class name itself, and not an instance of a class (an object), then we know that ‘out’ must be a static variable, since only static variables can be called with just the class name itself. So now we know that ‘out’ is a static member variable belonging to the System class.
Noticing the fact that ‘println()’ is clearly a method, we can further classify the ‘out’ in System.out.println(). We have already reasoned that ‘out’ is a static variable belonging to the class System. But now we can see that ‘out’ must be an instance of a class, because it is invoking the method ‘println()’.
The thought process that one should use to arrive at an answer is purposely illustrated above. Without knowing the exact answer beforehand, you can arrive at an approximate one by applying some basic knowledge of Java. Most interviewers wouldn’t expect you to know how System.out.println() works off the top of your head, but would rather see you use your basic Java knowledge to arrive at an answer that’s close to exact.
The more exact answer to the original question is this: inside the System class is the declaration of ‘out’ that looks like: ‘public static final PrintStream out’, and inside the Prinstream class is a declaration of ‘println()’ that has a method signature that looks like: ‘public void println()’.
Here is what the different pieces of System.out.println() actually look like:
//the System class belongs to java.lang package
class System {
public static final PrintStream out;
//...
}
//the Prinstream class belongs to java.io package
class PrintStream{
public void println();
//...
}
回答4:
System.out is provided by the JVM. By the time your main method is called, System.out is open and ready for use.
See http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#out
回答5:
In the Oracle Java runtime libraries, it is instantiated natively using the registerNatives()
native method which is called (via a static
initializer) on loading the System
class. This is however an implementation detail.
You can also set System.out
directly using System.setOut()
.
回答6:
Out in System.out.pritln is a static field (object) of PrintWriter in System class and println is a method of PrintWriter.
Reference :
System : 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
回答7:
There is no need to go for net and documentation even. We can simply say javap java.lang.System this gives you list of all static fields, method prototypes that belong to System class.
We can get details of any java class using javap, provided you know its package and classname
out is public static object of PrintStream defined in System class.
回答8:
When System class get initialized, it calls its initializeSystemClass()
method, here is the code:
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
In this code setOut0()
is a native function implemented in System.c:
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);
}
This is a standard JNI code that sets System.out to the argument passed to it, this method calls the native method setOut0() which sets the out variable to the appropriate value.
System.out
is final, it means it cannot be set to something else in initializeSystemClass() but using native code it is possible to modify a final variable.
回答9:
out is an object PrintStream class defined in System class. out is declared as public, static and final.
- println() is a method of PrintStream class.
- The println() method is called with out object.
- The out object is called with System class.
回答10:
System.out.println();
here println is an object of printstream class.We can't directly create object for printstream class. Out is an object of system class. out is called field in system class. while calling system.out it indirectly creates object for printstream class. hence we can call println() method using System.out.prontln().