aspose file tools*
The moose likes Beginning Java and the fly likes  How does System.out.println() work? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark " How does System.out.println() work?" Watch " How does System.out.println() work?" New topic
Author

How does System.out.println() work?

frank davis
Ranch Hand

Joined: Feb 12, 2001
Posts: 1479
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

Joined: Feb 22, 2001
Posts: 399
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

Joined: Feb 12, 2001
Posts: 1479
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

Joined: Feb 22, 2001
Posts: 399
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

Joined: Feb 12, 2001
Posts: 1479
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

Joined: Feb 22, 2001
Posts: 399
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

Joined: Feb 12, 2001
Posts: 1479
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

Joined: Jul 22, 2000
Posts: 9047
    
  10
public final static PrintStream out = nullPrintStream();

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


JavaBeginnersFaq
"Yesterday is history, tomorrow is a mystery, and today is a gift; that's why they call it the present." Eleanor Roosevelt
frank davis
Ranch Hand

Joined: Feb 12, 2001
Posts: 1479
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

Joined: Feb 22, 2001
Posts: 399
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

Joined: Feb 12, 2001
Posts: 1479



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

Joined: Feb 22, 2001
Posts: 399
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

Joined: Feb 12, 2001
Posts: 1479
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

Joined: Feb 22, 2001
Posts: 399
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

Joined: Feb 12, 2001
Posts: 1479
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

Joined: Feb 22, 2001
Posts: 399
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

Joined: Feb 12, 2001
Posts: 1479
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

Joined: May 26, 2001
Posts: 149
John Dale ...
What do you mean by nature maethods?
Thanks in advance
John Dale
Ranch Hand

Joined: Feb 22, 2001
Posts: 399
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():
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How does System.out.println() work?