thinking in java (二十六) ----- System.out.println("hello world")原理

我们首先来看System.out.println("hello world")的流程,先看看System类中out的定义

public final class System {
    ...

    public final static PrintStream out = null;

    ...
}

从中,我们可以发现:

1,out是System中的一个静态变量

2,out是PrintStream对象,PrintStream中有很多重载的println方法

我们知道了out是PrintStream对象,接下来看它是如何被初始化的,是怎么和屏幕输出关联的?

首先我们System类,先看其中的初始化方法,initialSystemClass()方法。

源码如下:

 1 private static void initializeSystemClass() {
 2 
 3     props = new Properties();
 4     initProperties(props);  // initialized by the VM
 5 
 6     sun.misc.VM.saveAndRemoveProperties(props);
 7 
 8     lineSeparator = props.getProperty("line.separator");
 9     sun.misc.Version.init();
10 
11     FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
12     FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
13     FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
14     setIn0(new BufferedInputStream(fdIn));
15     setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
16     setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
17 
18     loadLibrary("zip");
19 
20     Terminator.setup();
21 
22     sun.misc.VM.initializeOSEnvironment();
23 
24     Thread current = Thread.currentThread();
25     current.getThreadGroup().add(current);
26 
27     setJavaLangAccess();
28 
29     sun.misc.VM.booted();
30 }

我们只需要关注12 15行代码:即

FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);

setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));

将这两句话细分,可以划分为以下几步:

1,FileDescriptor fd = FileDescriptor.out;

2,FileOutputStream fdOut = new FileOutputStream(fd);

3,BufferedOutputStream bufOut = new BufferedOutputStream(fdOut, 128);

4, PrintStream ps = new PrintStream(bufout, true);

5,setOut0(ps);

 

说明:

1,获取FileDescriptor类中的静态成员out,out是FileDescriptor对象,他实际上是“标准输出(屏幕)”的标志符。

2,创建“标准输出(屏幕)”对应的“文件输出流,

3,创建文件输出流对应的缓冲输出流,目的是为了给文件输出加上缓冲的功能

4,创建缓冲输出流对应的“打印输出流”,目的是为了给“缓冲输出流”,如print,ptintln等,使其能够方便打印输出

5,执行setOut0(ps);

第五步的的setOut(ps),查看System.class中的源码,关于setOut0()的申明,如下:

private static native void setOut0(PrintStream out);

从中我们可以发现setOut()是一个native方法,我们可以查看源码(我看不懂)可以总结,setOut(PrintStream ps)的作用是:将ps设置为System类的out静态变量

前面已经说过,FileDescriptor.out就是机器的标准输出的文件标志符,我们可以通俗地将文件标志符理解为:FileDescriptor就是代表的“标准输出”,因此在initialSystemClass()中,上面的五步就是讲FileDescriptor.out封装了起来,封装后的System.in既有缓冲功能,又有便利的操作接口,如print,println,ptintf。

 

原文:http://www.cnblogs.com/skywang12345/p/io_17.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值