I am trying to get a better understanding for exactly what is going on behind the scenes with the following code:
[codse]System.out.println("Hello World");
As far as I can see the following happens:
The string "Hello World" is passed to the println method of class : java.io.PrintStream
Looking at the source code for println from PrintStream :
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
print method from class PrintStream is then called :
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
and then write method is called from class PrintStream :
private BufferedWriter textOut;
private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush && (s.indexOf('\n') >= 0))
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
which then calls method textOut.write() from class BufferedWriter which is an inherited method from class Writer :
public void write(String str) throws IOException {
write(str, 0, str.length());
}
which then calls the same method but with different signature construction:
private char[] writeBuffer;
public void write(String str, int off, int len) throws IOException {
synchronized (lock) {
char cbuf[];
if (len <= writeBufferSize) {
if (writeBuffer == null) {
writeBuffer = new char[writeBufferSize];
}
cbuf = writeBuffer;
} else { // Don't permanently allocate very large buffers.
cbuf = new char[len];
}
str.getChars(off, (off + len), cbuf, 0);
write(cbuf, 0, len);
}
}
which in turn calls getChars() method of class String which reads individual characters from the original string "Hello World" into the array of chars writeBuffer and then copies writeBuffer to cbuf which is also an array of chars.
Then the abstract write() method is called which is overridden in BufferedWriter.
public void write(char cbuf[], int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
if ((off < 0) || (off > cbuf.length) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
if (len >= nChars) {
/* If the request length exceeds the size of the output buffer,
flush the buffer and then write the data directly. In this
way buffered streams will cascade harmlessly. */
flushBuffer();
out.write(cbuf, off, len);
return;
}
int b = off, t = off + len;
while (b < t) {
int d = min(nChars - nextChar, t - b);
System.arraycopy(cbuf, b, cb, nextChar, d);
b += d;
nextChar += d;
if (nextChar >= nChars)
flushBuffer();
}
}
}
and I am guessing that the crucial line which actually makes the pixels on my screen light up in a "Hello World" arrangement is:
System.arraycopy(cbuf, b, cb, nextChar, d);
as it refers to System class and this communicates with the operating system to ultimately communicate with the video driver and graphics card which makes the sweet innocent little pixels greet the world so adorably. My problem, if you have had the patience to get this far, is that the source code for System.arraycopy is :
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
which is defined in a final class and hence can not be overridden. Where is the code for arraycopy ??? And more to the point am I in the right ball park or is it more to do with the flush() method. And if so how?
Thank you for reading this and helping me get my head around it.
H