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 ?
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.
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.
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
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().
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
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.
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.
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().
Related
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 ?
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.
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.
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
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().
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
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.
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.
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().
I am just a newbie in Java. I was wondering the way System.out.println() is used. Out is a static field inside System class. The type of out is PrintStream. But when I saw the constructor of PrintStream class, it takes a parameter of type OutputStream and as far as I know we cannot create the object of an abstract class. In that case we must pass some subclass's object to the constructor of PrintStream. What is that class? Same is the System.in. It is also InputStream's reference but what is the type of object it points to as the InputStream is abstract?
PrintStream wraps BufferedOutputStream, which wraps FileOutputStream, which is writing into the console, which has its own FileDescriptor.
A simple way to view the structure of a class is to examine it in a debugger.
As you can see #Andremonify's description is basically what you have.
FileDescriptor
0 is System.in
1 is System.out
2 is System.err
3+ is used for other files
Yes out is of PrintStream type. And constructor of PrintStream takes OutputStream type. OutputStream is abstract class. But any superclass refrence can refer subclass object without casting, so PrintStream's constructor has OutputStream refrence, but this refrence must be referring one of OutputStream's subclass like FileOutputStream
There are a couple more things to say about the implementation of System.out.
The actual implementation class of System.out is not specified. The javadocs don't say what it is. We observe (in various way) that Oracle Java and OpenJDK Java implement the "stack" in a particular way (see other answers), but this could change in the future.
The System::setOut(PrintStream) method can be used to modify what System.out is bound to. If that happens, any assumptions about implementation classes may be incorrect.
It turns out that you can do this:
System.setOut(null);
so System.out could be null. However, with current implementations, System.out won't be null unless you set it to null.
All that is actually guaranteed by the specifications is that the value of System.out will have a type that is assignment compatible with PrintStream.
I'm a beginner learning Java with some knowledge of C++, and the System.out.println(); is confusing me right now. So System is the class, out is a variable that can call a method?? According to: http://journals.ecs.soton.ac.uk/java/tutorial/getStarted/application/objects.html
out is a class variable, and a variable is a storage location in the computer memory that has a type name and content. It's not an object like string that can use methods like .getLength(). The way the website explains it is that out refers to an instance of PrintStream class, but how?
It's not an object
This is where your reasoning is going wrong. System.out is (a reference to) an object.
The type of the reference is PrintStream, as documented in the Javadoc. This means that you can call PrintStream's methods on System.out, e.g.:
System.out.println();
out doesn't call a method : out is a variable holding an object (an instance of PrintStream) on which you can call a method.
For example :
System.out.println("hey!");
You could also do
void print(PrintStream ps, Object o) {
ps.println(o);
}
...
print(System.out, "hey!");
More strictly, it's a public static field that is a reference to an object of type PrintStream, so yes, you can call methods on it.
Java references are roughly analogous to C pointers (at least in the way they are used, obviously there are significant differences).
Out is a public static field of the class named System.
Because it's public, you can call methods on it.
Its type is PrintStream.
The best way to learn is to read the documentation:
http://docs.oracle.com/javase/6/docs/api/java/lang/System.html
Notice the part at the top where it describes in, out, and err.
System.out is a particular instance of PrintStream, whose output is linked to the equivalent of the C++ stdout
System is a final class which has a final variable out holding a object of PrintStream class on which we can call println() method.
Actually the out parameter in System.out.println(String args[]) is a static field in System class. Whenever a field is declared it should have certain datatype. In this class the out field is defined as static PrintStream out;.
It means the datatype of out is PrintStream class.In this way System.out will actually represents a object of PrintStream class. With this object we are calling println() method of PrintStream class.
Think of System class roughly like this :
package java.lang;
public final class System {
public final static PrintStream out;
}
here out is a static final variable of "type" Printstream.
Since it is a static variable, we can call it by "ClassName.variableName" without creating any object of System class, so we do System.out.
Now, out is a reference variable of "PrintStream" class. Till now, only this reference variable is created and it is not referring to any "object" of Printstream class.
But System class creates object of PrintStream when it is loaded in memory.
For this, see methods initializeSystemClass() and setOut0() in below link which is complete source code of System class. (Dont be overwhelmed by this enormous code, just be assured that there is "new PrintStream()" called inside System (here at line 1095)).
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/System.java
so, when we have an object of PrintStream class, our out reference variable can easily call a method on it, right? This is how we call System.out.println()
Is JNI's "method signature" different if method is defined to return (static) interface ?
In my Java class I have this method:
public SharedPreferences.Editor getSharedPrefsEditor() {
return mActivity.getPreferences(Context.MODE_PRIVATE).edit();
}
SharedPreferences.Editor is a static interface in SharedPreferences.
In my C++ JNI code I do this:
// 'env' is the java environment that JNI passes to us
// 'jObject' is the one that JNI passes to us (along with env)
jclass javaCallerClass = env->GetObjectClass(jObject);
jmethodID methodId_getSharedPrefsEditor = env->GetMethodID(
javaCallerClass,
"getSharedPrefsEditor",
"()Landroid/content/SharedPreferences/Editor;");
For some odd reason, this doesn't work. It compiles, but at runtime I get this:
DEBUG/dalvikvm(19020): GetMethodID:
method not found:
Lcom/mangotaster/madballs/MyRenderer;.getSharedPrefsEditor:()Landroid/content/SharedPreferences/Editor;
I'm calling other methods in that class in pretty much the same way without any problems.
The only change seems to be the return value.
I did try to call the edit() function straight from JNI code, but got the same error - which makes me believe that my function signature "()Landroid/content/SharedPreferences/Editor;" is indeed wrong.
More info on the SharedPreferences class.
Nested/Inner classes don't use the standard namespace nomenclature in JNI signatures. The inner class is actually translated to a normal class at the same level as the outer class by the Java compiler with the name "Outer$Inner". I think you want "()Landroid/content/SharedPreferences$Editor;".
No need to guess about this, or ask on forums ;-) javap -s will tell you the correct JNI signature string for any Java method.
System.out is declared as public static final PrintStream out.
But you can call System.setOut() to reassign it.
Huh? How is this possible if it's final?
(same point applies to System.in and System.err)
And more importantly, if you can mutate the public static final fields, what does this mean as far as the guarantees (if any) that final gives you? (I never realized nor expected System.in/out/err behaved as final variables)
JLS 17.5.4 Write Protected Fields:
Normally, final static fields may not be modified. However System.in, System.out, and System.err are final static fields that, for legacy reasons, must be allowed to be changed by the methods System.setIn, System.setOut and System.setErr. We refer to these fields as being write-protected to distinguish them from ordinary final fields.
The compiler needs to treat these fields differently from other final fields. For example, a read of an ordinary final field is "immune" to synchronization: the barrier involved in a lock or volatile read does not have to affect what value is read from a final field. Since the value of write-protected fields may be seen to change, synchronization events should have an effect on them. Therefore, the semantics dictate that these fields be treated as normal fields that cannot be changed by user code, unless that user code is in the System class.
By the way, actually you can mutate final fields via reflection by calling setAccessible(true) on them (or by using Unsafe methods). Such techniques are used during deserialization, by Hibernate and other frameworks, etc, but they have one limitation: code that have seen value of final field before modification is not guaranteed to see the new value after modification. What's special about the fields in question is that they are free of this limitation since they are treated in special way by the compiler.
Java uses a native method to implement setIn(), setOut() and setErr().
On my JDK1.6.0_20, setOut() looks like this:
public static void setOut(PrintStream out) {
checkIO();
setOut0(out);
}
...
private static native void setOut0(PrintStream out);
You still can't "normally" reassign final variables, and even in this case, you aren't directly reassigning the field (i.e. you still can't compile "System.out = myOut"). Native methods allow some things that you simply can't do in regular Java, which explains why there are restrictions with native methods such as the requirement that an applet be signed in order to use native libraries.
To extend on what Adam said, here is the impl:
public static void setOut(PrintStream out) {
checkIO();
setOut0(out);
}
and setOut0 is defined as:
private static native void setOut0(PrintStream out);
Depends on the implementation. The final one may never change but it could be a proxy/adapter/decorator for the actual output stream, setOut could for example set a member that the out member actually writes to. In practice however it is set natively.
the out which is declared as final in System class is a class level variable.
where as out which is in the below method is a local variable.
we are no where passing the class level out which is actually a final one into this method
public static void setOut(PrintStream out) {
checkIO();
setOut0(out);
}
usage of the above method is as below:
System.setOut(new PrintStream(new FileOutputStream("somefile.txt")));
now the data will be diverted to the file.
hope this explanation makes the sense.
So no role of native methods or reflections here in changing purpose of the final keyword.
As far as how, we can take a look at the source code to java/lang/System.c:
/*
* The following three functions implement setter methods for
* java.lang.System.{in, out, err}. They are natively implemented
* because they violate the semantics of the language (i.e. set final
* variable).
*/
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);
}
...
In other words, JNI can "cheat". ; )
I think setout0 is modifying local level variable out, it can't modify class level variable out.