System.out.println("Hello World")是大部分程序员入门的第一行代码,也可以说是程序员们最熟悉的一行代码。大家真的深入研究过System.out.println()么?今天就来盘一盘System.out.println()!
 

System是个啥?

System作为Java.lang包中一个final类,早在JDK1.0中就存在其中,可谓基石也。
 

再来看看out

out是System中的一个静态的数据成员,但这个成员不是基本类,而是java.io.PrintStream类的对象。out被关键字static修饰,我们可以直接通过System.out来引用,而无须先建立对象。
public final static PrintStream out = null;

out在系统类初始化时被实例化,配置输出在控制台上。

private static void initializeSystemClass() {

    props = new Properties();
initProperties(props); // initialized by the VM sun.misc.VM.saveAndRemoveProperties(props); lineSeparator = props.getProperty("line.separator");
sun.misc.Version.init(); FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
// 获取 FileDescriptor中的静态成员 out并创建对应的文件输出流。out是一个 FileDescriptor对象,它是"标准输出(屏幕)"的标识符。
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn));
//标准输出编码
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding"))); loadLibrary("zip"); Terminator.setup(); sun.misc.VM.initializeOSEnvironment(); Thread current = Thread.currentThread();
current.getThreadGroup().add(current); setJavaLangAccess(); sun.misc.VM.booted();
} //native方法 输出
private static native void setOut0(PrintStream out);

out对象是可以自定义的。开发人员可以在执行期间对out对象进行修改。

public static void setOut(PrintStream out) {
checkIO();
setOut0(out);
}

例:修改out输出路径,将结果以文档形式输出

public class ModifyOut {
public static void main(String args[]) {
System.setOut(new PrintStream(new FileOutputStream("ModifyOut.txt")));
System.out.println("out输出已经重定向!");
}
}

最后是printl()

println()中的传入参数包含了各种各样的参数类型,枚举了一下。
java.io.PrintStream#println()
java.io.PrintStream#println(boolean)
java.io.PrintStream#println(char)
java.io.PrintStream#println(char[])
java.io.PrintStream#println(double)
java.io.PrintStream#println(float)
java.io.PrintStream#println(int)
java.io.PrintStream#println(long)
java.io.PrintStream#println(java.lang.Object)
java.io.PrintStream#println(java.lang.String)

各种参数的println()方法内容大同小异,这里以println(Object x)为例,盘一下println()中都干了些啥。

public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}

使用println()方法中的大部分参数,在执行write(s)方法前,通通被转换成String类型。仅char[] 并没有转换成String类型。原因嘛。嘿嘿,String类型就是char[]实现的啊。

public void print(String s) {
if (s == null) {
s = "null";
}
// 传入的参数在执行write(s)方法前,通通都被转成String类型。
write(s);
}

操劳多种类型进行String类型转换,就是为了这步write(String s)方法集中统一处理

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;
}
}
/**
* writeBuffer的大小 默认为1024
*/
private static final int WRITE_BUFFER_SIZE = 1024; public void write(String str) throws IOException {
write(str, 0, str.length());
} public void write(String str, int off, int len) throws IOException {
synchronized (lock) {
char cbuf[];
if (len <= WRITE_BUFFER_SIZE) {
if (writeBuffer == null) {
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
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);
}
} // 将字符数组buffer写入到输出流中,offset是从buffer中读取数据的起始偏移位置,len是读取的长度。
abstract public void write(char cbuf[], int off, int len) throws IOException;

盘一盘 System.out.println()的更多相关文章

  1. windows下制作linux U盘启动盘或者安装优盘(转)

    windows下制作linux U盘启动盘或者安装优盘(转) Linux发行版排行榜:http://iso.linuxquestions.org/ [方案一]:UltraISO(不推荐,在Window ...

  2. Linux U盘 启动盘

    /****************************************************************************** * Linux U盘 启动盘 * 说明: ...

  3. Java基础-重写System.out.println方法

    PrintStream myStream = new PrintStream(System.out) { @Override public void println(String x) { super ...

  4. U盘启动盘的制作--用U盘硬装Windows系统、或是重装Windows系统

    借助IT天空的优启通U盘启动盘的制作--用U盘装Windows系统.或是重装Windows系统之U盘启动盘的制作 1.==================================== 2.== ...

  5. 制作centos的U盘启动盘

    制作centos的U盘启动盘比ubuntu麻烦一些,因为可能涉及到fat32文件格式不支持大于4G的文件存储的问题,而最新版本的centos就是大于4G的,所以就需要对U盘进行分区. 一个做主引导,一 ...

  6. U盘启动盘 安装双系统 详细教程

    U盘启动盘 安装win7+linux双系统 最近在看鸟哥的linux 私房菜 ,看到多重系统那部分,自然的安装多重系统的激情由此而燃.在网上看了很多资料,感觉都不全.经过艰辛的摸索,终于被我发现了一个 ...

  7. System.out.println与System.err.println的区别(输出顺序!!!)

    System.out.println与System.err.println的区别(输出顺序!!!) 分类:java (208)  (0) System.out.println与System.err.p ...

  8. IntelliJ中的main函数和System.out.println()快捷键

    1.在IntelJ中和Eclipse中稍有不同,在Eclipse中,输入main再按Alt+/即可自动补全main函数,但是在IntellJ中则是输入psvm,选中即可 2.在方法体内部有for循环, ...

  9. 制作U盘启动盘及安装操作系统的方法

    U盘启动盘制作方法: 1.从网上下载最新的老毛桃U盘启动制作工具主程序并安装 2.插入U盘(制作启动盘前先保存好你的资料到其它地方,以防丢失不可找回) 3.插入正确的U盘后程序会自动检测到U盘,启动模 ...

随机推荐

  1. memcached的使用一

    1.安装memcached  需要一个memcache.exe文件,打开cmd窗口,切换到可执行文件目录,执行memcache -的install命令. 2.连接服务 做测试可以打开电脑的telnet ...

  2. 最小二乘法 good

    最小二乘法也称为最小平方法,是一种数据优化技术,它通过最小化误差的平方和寻找数据的最佳函数匹配. 最小二乘法最初由高尔顿在创立回归分析的时候提出,现在已经成为探索变量间关系最重要的方法,最小二乘法根据 ...

  3. 修改GitHub上项目语言显示

    问题 最近将自己以Scala为主语言写的博客放到github上了.由于使用了富文本编辑器.jQuery.Bootstrap等第三方插件,导致js.css等代码远远超过你自己写的代码. 于是也就成这样了 ...

  4. 值得推荐的C/C++框架和库(深度好文)

    [本文系外部转贴,原文地址:http://www.cppblog.com/merlinfang/archive/2014/12/26/209311.html http://coolshell.info ...

  5. Qt5.5以来对Network的改进(包括对SSL的功能支持,HTTP的重定向等等)

    Qt Network New SSL back-end for iOS and OS X based on Secure Transport. Note that in Qt 5.6 this wil ...

  6. Microsoft.Ace.OleDb.12.0 操作excel

    在用c#操作excel的时候,碰到了一下的问题: 1.Microsoft.Ace.OleDb.12.0未安装,可以到下载2007 Office system 驱动程序AccessDatabaseEng ...

  7. 搭建RPC over HTTP 环境遇到的问题

    最近需要做RPC的IPS协议分析,需要了解一下RPC over HTTP的协议格式,由于此类数据包不易构造,故此想搭建一个抓一些包分析一下. 结果搭建这么个环境硬是用了我四个工作日的时间,崩溃加无语. ...

  8. Codility---BinaryGap

    Task description A binary gap within a positive integer N is any maximal sequence of consecutive zer ...

  9. SYN5301型 时间检定装置

      SYN5301型  时间检定装置 夹具概述 我们的夹具可以水平放置测秒表,也可以垂直测秒表,而其他厂家的夹具只能水平放置测,如果想垂直测的话得依靠在墙上或者是其他的物体上来测,这样的检测出来的数据 ...

  10. ZooKeeper入门(二) Zookeeper选举

    1 背景 1.1 什么是leader选举 在zookeeper集群中,每个节点都会投票,如果某个节点获得超过半数以上的节点的投票,则该节点就是leader节点了 1.2 zookeeper集群选举le ...