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. 程序异常崩溃后用windbg辅助调试解决的经验 以及 堆栈问题调试经验

    1,程序异常崩溃后用windbg辅助调试解决的经验  状况:我的程序调用别人的库做 文件写入工作. 在这一过程中出现异常,程序崩溃. 经反复检查,认为自己的程序没有错,但无法判断在别人库里哪里有错. ...

  2. WebAPI增加Area以支持无限层级同名Controller

    原文:WebAPI增加Area以支持无限层级同名Controller 微软的WebAPI默认实现逻辑 默认实现中不支持同名Controller,否则在访问时会报HttpError,在网上找到了各种路由 ...

  3. 使用Visual Studio开发Python

    Python优秀的集成开发环境有PyCharm,Visual Studio Code等,当然你仍然可以使用Visual Studio进行开发.如果你熟悉Visual Studio,使用Visual S ...

  4. ML:吴恩达 机器学习 课程笔记(Week5~6)

    Neural Networks: Learning Advice for Applying Machine Learning Machine Learning System Design

  5. ASP.NET Core Linux 发布

    这篇博客参考了以下文章: 1.http://www.cnblogs.com/ants/p/5732337.html 2.http://www.linuxidc.com/Linux/2016-11/13 ...

  6. msys2 安装笔记(可以按照这个关键字搜索)

    以前一直在用 msys,最近发现还有个 msys2,并且msys2 配套的编译器是MinGW-w64. 就试着用了用,感觉还不错,这里把安装过程记录一下. 简单的说,MSYS2 是MSYS的一个升级版 ...

  7. 开源玩家福利:十大Linux免费游戏

    假如当你考虑从Windows平台迁移至Linux平台时,“我能在Linux平台上游戏吗?”这类疑问正困扰着你,那么对此这有一个答案就是“快去Linux平台吧!”.感谢开源组织一直以来坚持不懈为Linu ...

  8. 比较DirectX和OpenGL的区别(比较详细)

    OpenGL是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库.OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL.IRIS GL是一个工业标准的3D图形软件接口,功能虽然 ...

  9. c# json key转大小写

    有需求需要将json的字段转换为小写,使用正则表达式实现,代码如下 正则表达式为   \"[a-zA-Z0-9]+\"\s*: MatchCollection ms = Regex ...

  10. Ansible的安装与使用初探

    一.环境准备 网络配置 管理端:192.168.237.201 受控端:192.168.237.202.192.168.237.203(一共2台) 硬件信息 CPU:1核 内存:512MB 磁盘:10 ...