• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How does System.out.println() work?

 
frank davis
Ranch Hand
Posts: 1479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The class System has a PrintStream field called "out" that has a non static method called println(). "out" has to reference a Printstream object, but how exactly is that object created?
Is there some way I can see that code in the System class?
 
John Dale
Ranch Hand
Posts: 399
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Check your JDK install directory for a file called src.jar. If you unzip that file, you will find illustrative source much of the standard Java library, including System. In 1.3.1, the standard files are initialized in initializeSystemClass(), near the bottom of the file. Essentially, it wraps what it is passed by the underlying operating system.
 
frank davis
Ranch Hand
Posts: 1479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the info. I never actually saw where an object is assigned to "out". I bet it happens in the native setOutO method but I can't find anything on that.
Also the doc says initializeSystemClass is "called after thread initialization". I'm having trouble tracing the flow of events when java begins. Does the JVM call System methods or does it call some other class that starts the whole ball rolling?
 
John Dale
Ranch Hand
Posts: 399
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My guess is that native methods are used to change the field System.out because it is final, and hence not accessible for at this point modification using JVM instructions.
It appears that the System class has a very special relationship with the JVM. Perhaps some of the detail of the JVM initialization are described in the Java Language Specification and the Java Virtual Machine Specification.
 
frank davis
Ranch Hand
Posts: 1479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is a curious lack of information in JLS and JVM doc on the System class and its initialization. There's actually nothing. I would expect more since System.out.println() is used so often...
 
John Dale
Ranch Hand
Posts: 399
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What more are you trying to understand about System.out? It appears that when the JVM is initialized, the it takes the standard output file passed by the native OS, and wraps it up in the Java classes you see in the source. All of this is done before any user code is called.
 
frank davis
Ranch Hand
Posts: 1479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Basically I was just hoping to see the code where the "out" object is created, since it must be created to use its non static println() method. This is proving curiously difficult.
<i>It appears that when the JVM is initialized, the it takes the standard output file passed by the native OS, and wraps it up in the Java classes you see in the source. All of this is done before any user code is called. <i>
There's very little doc to support this assumption.

Maybe the JVM calls the native static method SetOutO somehow (how?) that i suspect creates the out method. Since its a native method maybe there is no Java code involved. But when is SetOutO called, every time we do System.out.println()?
What exactly happens when the JVM starts up? What initialiazation is done, what classes are called and in what order?
Confusing me more, Someone said when you have a static reference to an object the JVM somehow automatically creates the object for you without any explicit new() or constructor needed.
[ April 29, 2002: Message edited by: herb slocomb ]
 
Marilyn de Queiroz
Sheriff
Posts: 9066
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
public final static PrintStream out = nullPrintStream();

is line 81 in the java.lang.System class.
Is this what you're looking for?
 
frank davis
Ranch Hand
Posts: 1479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Marilyn deQueiroz:
public final static PrintStream out = nullPrintStream();

is line 81 in the java.lang.System class.
Is this what you're looking for?

That doesn't seem to create an out object. I want to see an out object get created, or if that can't be done, some authoritative doc specifying what exactly goes on when the JVM starts up (the order in which things are initialzed) that causes out to be created.
 
John Dale
Ranch Hand
Posts: 399
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Numbering the points for reference:

(A) Basically I was just hoping to see the code where the "out" object is created, since it must be created to use its non static println() method. This is proving curiously difficult.
(B) Re: <i>It appears that when the JVM is initialized, the it takes the standard output file passed by the native OS, and wraps it up in the Java classes you see in the source. All of this is done before any user code is called. <i>
(C) There's very little doc to support this assumption.
(D) Maybe the JVM calls the native static method SetOutO somehow (how?) that i suspect creates the out method. Since its a native method maybe there is no Java code involved. But when is SetOutO called, every time we do System.out.println()?
(E) What exactly happens when the JVM starts up? What initialiazation is done, what classes are called and in what order?
(F) Confusing me more, Someone said when you have a static reference to an object the JVM somehow automatically creates the object for you without any explicit new() or constructor needed.

(A) There is no "out" object. System.out is a final static field in the System class, which holds a reference to a PrintStream (by the time user code is loaded).
(B) Remarks on which we elaborate below.
(C) Perhaps there is not a great deal of documentation beyond the code, but consider these code fragments:

I'm not sure what is obvious and what is not, so I'll step through it in detail.
1) The variable FileDescriptor.out is set to 1, which is the standard file descriptor number for a process's standard output stream supplied by the operating system. (See, for example, Unix, Windows, C, or C++ system or software development documentation.)
2) The method initializeSystemClass() is called. It obvious that this is called before user stuff is allowed to run, since it initiaizes stuff, such as out and system properties, that are guaranteed to be there for user classes. THis method creates a FileOuputStream tied to the file descriptor.
3) The FileOutputStream is then wrapped in a BufferedOutputStream and a PrintStream. This is where the PrintStream object is created, during system initialization, before user stuff is loaded.
4) A reference to this newly created PrintStream is saved in the final static field System.out, where it can be accessed by the expression System.out, and hence used in statements like System.out.println("xyzzy"). However, since the field is final, the JVM cannot be used to save a value there after the System constructor is run. It seems obvious that they created a native method (that is, C code) called setOut0() to do that. Since setOut0() is running machine language code that is not under the control and constraints of the JVM, it can dabble with anything that it knows how to find.
(D) There is no "out" method. The "out" in System.out.println() is a final static field in System that contains a reference to a PrintStream object, which has a println() method. setOut0(PrintStream out) probably does nothing more than than save the value of its argument in the out field of System. This setOut0() is a private method of System, so it cannot be called from outside System (except by bypassing normal access rules), and the only place it is called in System is in initializeSystemClass(), supporting the notion that it is run only during system initiailization.
(E) I have no idea. Some of this is documented in the Java Language Specification, and I suspect more is documented in the Java Virtual Machine Specification.
(F) The system automaticially creates the static fields within class when the class is loaded by the ClassLoader which is normally invoked by the JVM. This process is detailed in the Java Language Specification. However, having a "static reference to an object" does not cause the JVM to create that object for you. A static reference to a class will cause the class loader to load that class, initializing the static fields of that class according to the static initializers and default values. But I'm not sure this is what you are talking about.
 
frank davis
Ranch Hand
Posts: 1479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator



4) A reference to this newly created PrintStream is saved in the final static field System.out...

I missed where the PrintStream reference assignment is made to System.out.

However, since the field is final, the JVM cannot be used to save a value there after the System constructor is run.

I thought final for a variable just meant the value couldn't be changed.

(E) I have no idea. Some of this is documented in the Java Language Specification, and I suspect more is documented in the Java Virtual Machine Specification.

There's really nothing I could find in either JVM doc or JLS doc that deals with the steps that occur prior to loading/running a user class. The initializeSystemClass method can't be the first
thing to run because the comments say its called after thread initialization.
I guess the JVM is hardcoded in some way to create a thread to run everything in, then its hardcoded to call initializeSystemClass, then somewhere, somehow System.out is assigned a reference to a PrintStream object.
 
John Dale
Ranch Hand
Posts: 399
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Right. I don't see this initialization spelled out in the JLS or JVMS. That is initializeSystemClass() is called before user classes are loaded in a conclusion on my part, not something I read.
I was wrong in saying that setOut0() not used except in initializedSystemClass(). It is called from setOut(), which is part of the public API.
This helps clear up any mystery about setOut0(). A look at the documentation and code for setOut() make it seem clear that setOut0() updates the System.out field, bypassing the "final" constraint. It must also do some synchronization trick to ensure that all threads see the modified System.out field and the object to which it points, since setOut() is callable at any time by anyone.
 
frank davis
Ranch Hand
Posts: 1479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by John Dale:
Right. I don't see this initialization spelled out in the JLS or JVMS. That is initializeSystemClass() is called before user classes are loaded in a conclusion on my part, not something I read.

Seems like a reasonable conclusion. I wonder how many other steps are not specified in the doc...


This helps clear up any mystery about setOut0(). A look at the documentation and code for setOut() make it seem clear that setOut0() updates the System.out field, bypassing the "final" constraint. It must also do some synchronization trick to ensure that all threads see the modified System.out field and the object to which it points, since setOut() is callable at any time by anyone.

So System.out gets a reference to its Printstream object in setOut() which calls setOut0(). I saw code in http://developer.java.sun.com/developer/TechTips/2000/tt0815.html that seems to put our conclusions to some use by using sample code that shows how to change the standard output. So, we could have System.out.println() output to a file or something else.

Is there any doc on setOut0()?
Thanks for helping me solve some of this mystery.
[ April 29, 2002: Message edited by: herb slocomb ]
 
John Dale
Ranch Hand
Posts: 399
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the sample code in src.jar for JDK1.3.1, initializeSystemClass() seems call setOut0() directly, instead of calling setOut(), thus bypassing the security checks in checkIO() (or something link that.
I'd be surprised if there is further documentation of setOut0(), since it is a private method. Also, as I recall, the source in src.jar is only illustrative library code. The actual released Java runtimes may not be identical to src.jar.
 
frank davis
Ranch Hand
Posts: 1479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by John Dale:
Also, as I recall, the source in src.jar is only illustrative library code. The actual released Java runtimes may not be identical to src.jar.

Then I can't really know what's happening when I use the java classes. That sucks.
 
John Dale
Ranch Hand
Posts: 399
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It isn't a good idea to write code that depends on behavior that is not guaranteed by the published documentation. The JavaDoc for the API is a good start, and seems to meet most day-to-day needs. Those big fat Sun books on the Java class libraries provide some details not in the JavaDoc, and show stuff in context.
 
frank davis
Ranch Hand
Posts: 1479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh, I always wondered why anyone would buy the fat books. I had assumed all the same stuff was available online.
 
Mike Shn
Ranch Hand
Posts: 149
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
John Dale ...
What do you mean by nature maethods?
Thanks in advance
 
John Dale
Ranch Hand
Posts: 399
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Do you mean "native methods"?
I'm referring to a method declared in Java with the keyword "native". I think these are typically written in C and linked into Java using the Java Native Interface (JNI). I've never worked with JNI.
In particular, here is how System.java declares setOut0():
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic