Java 的 Hello World 代码
public class HelloWorld { /**
*
* @param args
*/ public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Hello World");
} }
编译执行
$ javac HelloWorld.java
$ java HelloWorld
Hello World
功能就是在控制台打印 Hello World 字符串, 我们这里深入每个步骤,探讨是怎样将字符串打印到控制台的。
环境
我们刚才的程序执行在 Ubuntu Linux 的控制台 bash 程序里。 javac 是编译器。 java 执行虚拟机。加载 HelloWorld.class 执行 HelloWorld 类的 main 函数,这部分是属于虚拟机的内容,临时不做考虑,我们主要从代码调用的步骤分析。
System 类
从代码逻辑上,我们非常easy看出是 System 类的 out 成员 println 函数运行了打印操作:
public final class System { /**
* Default input stream.
*/
public static final InputStream in; /**
* Default output stream.
*/
public static final PrintStream out; /**
* Default error output stream.
*/
public static final PrintStream err; private static final String lineSeparator;
private static Properties systemProperties; static {
err = new PrintStream(new FileOutputStream(FileDescriptor.err));
out = new PrintStream(new FileOutputStream(FileDescriptor.out));
in = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
lineSeparator = System.getProperty("line.separator");
}
out 是个 PrintStream
PrintStream 类
/**
* Prints a string followed by a newline. The string is converted to an array of bytes using
* the encoding chosen during the construction of this stream. The bytes are
* then written to the target stream with {@code write(int)}.
*
* <p>If an I/O error occurs, this stream's error state is set to {@code true}.
*
* @param str
* the string to print to the target stream.
* @see #write(int)
*/
public synchronized void println(String str) {
print(str);
newline();
}
详细的工作交给了 print , 我们在这个类里面能够看到 newline 仅仅是打印了两个特殊字符,换行。
public synchronized void print(String str) {
if (out == null) {
setError();
return;
}
if (str == null) {
print("null");
return;
} try {
if (encoding == null) {
write(str.getBytes());
} else {
write(str.getBytes(encoding));
}
} catch (IOException e) {
setError();
}
}
进一步的工作由 write 函数完毕:
public synchronized void write(int oneByte) {
if (out == null) {
setError();
return;
}
try {
out.write(oneByte);
int b = oneByte & 0xFF;
// 0x0A is ASCII newline, 0x15 is EBCDIC newline.
boolean isNewline = b == 0x0A || b == 0x15;
if (autoFlush && isNewline) {
flush();
}
} catch (IOException e) {
setError();
}
}
又来了个 out 这个。out 是 来自 OutputStream 的实现类 public class FileOutputStream extends OutputStream
public class FileOutputStream extends OutputStream { private FileDescriptor fd;
private final boolean shouldClose; /** The unique file channel. Lazily initialized because it's rarely needed. */
private FileChannel channel; /** File access mode */
private final int mode; private final CloseGuard guard = CloseGuard.get();
FileDescriptor
public final class FileDescriptor { /**
* Corresponds to {@code stdin}.
*/
public static final FileDescriptor in = new FileDescriptor(); /**
* Corresponds to {@code stdout}.
*/
public static final FileDescriptor out = new FileDescriptor(); /**
* Corresponds to {@code stderr}.
*/
public static final FileDescriptor err = new FileDescriptor(); /**
* The Unix file descriptor backing this FileDescriptor.
* A value of -1 indicates that this FileDescriptor is invalid.
*/
private int descriptor = -1; static {
in.descriptor = STDIN_FILENO;
out.descriptor = STDOUT_FILENO;
err.descriptor = STDERR_FILENO;
}
这里来到 STDOUT_FILENO。 该变量定义在: 在<stdio.h>。
STDIN_FILENO等是文件描写叙述符,是非负整数,一般定义为0, 1, 2,属于没有buffer的I/O。直接调用系统调用。在<unistd.h>。
參考i: http://blog.csdn.net/xiaoxi2xin/article/details/5524769
@Override
public void write(byte[] buffer, int byteOffset, int byteCount) throws IOException {
IoBridge.write(fd, buffer, byteOffset, byteCount);
} @Override
public void write(int oneByte) throws IOException {
write(new
最后是调用 os 的 write
版权声明:本文博客原创文章,博客,未经同意,不得转载。