正文
盘一盘 System.out.println()
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
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;
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;
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;