string 中维护了一个char数组的value值,打印的时候也就是打印的这个数组的值。但是print(str)参数为string类型
看print的源码
/** * Prints a String and then terminate the line. This method behaves as * though it invokes <code>{@link #print(String)}</code> and then * <code>{@link #println()}</code>. * * @param x The <code>String</code> to be printed. */ public void println(String x) { synchronized (this) { print(x); newLine(); } }
public void print(String s) {
if (s == null) { s = "null"; } write(s); }
private void write(String s) {
try { synchronized (this) { ensureOpen(); textOut.write(s);//java.io.BufferedWriter.write(s) textOut.flushBuffer(); charOut.flushBuffer();//java.io.OutputStreamWriter.flushBuffer(); if (autoFlush && (s.indexOf('\n') >= 0)) out.flush(); } }
//在看看write方法调用了getChars方法,这是输出string,char数组值的关键
public void write(String s, int off, int len) throws IOException { synchronized (lock) { ensureOpen(); int b = off, t = off + len; while (b < t) { int d = min(nChars - nextChar, t - b); s.getChars(b, b + d, cb, nextChar); b += d; nextChar += d; if (nextChar >= nChars) flushBuffer(); } } }
//最终调用了printStream方法的write方法
public void write(byte buf[], int off, int len) { try { synchronized (this) { ensureOpen(); out.write(buf, off, len); if (autoFlush) out.flush();//关键在这一步调用了java.io.BufferedOutputStream的flushBuffer方法 } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); }
java.io.BufferedOutputStream的flushBuffer方法
/** Flush the internal buffer */最终调用了java.io.FileOutputStream..write(buf, 0, count);方法 private void flushBuffer() throws IOException { if (count > 0) { out.write(buf, 0, count);//java.io.FileOutputStream..write(buf, 0, count); count = 0; } }
// java.io.FileOutputStream..write最终调用了writeBytes方法
public void write(byte b[], int off, int len) throws IOException { writeBytes(b, off, len); }
//writeBytesa方法是本地方法最终以byte数组输出
private native void writeBytes(byte b[], int off, int len) throws IOException;
jdK native code
JNIEXPORT void JNICALL
Java_java_io_FileOutputStream_writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off, jint len) { jboolean append = (*env)->GetBooleanField(env, this, fos_append); FD fd = GET_FD(this, fos_fd); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); return; } if (append == JNI_TRUE) { if (IO_Lseek(fd, 0L, SEEK_END) == -1) { JNU_ThrowIOExceptionWithLastError(env, "Append failed"); } } writeBytes(env, this, bytes, off, len, fos_fd); }