print()輸出後光標停留在行尾;println()輸出後自動換行,光標移至下行行首。
public class PrintDemo {
public static void main(String[] args) {
System.out.print("Hello");
System.out.print("World");
System.out.println(); // 輸出: HelloWorld (光標在下一行開頭)
System.out.println("Hello");
System.out.println("World");
// 輸出:
// Hello
// World
}
}
| 代碼 | 控制台輸出 | 光標最終位置 |
|---|---|---|
print("A"); print("B"); | AB | B 後(同一行) |
println("A"); println("B"); | A | B 後下一行行首 |
print("A"); println("B"); | AB | 下一行行首 |
println("A"); print("B"); | A | B 後(同一行) |
print = print(打印)println = print + ln (line,行) → 「打印並換行」// PrintStream.java 核心片段
public void print(String s) {
if (s == null) s = "null";
write(s); // 寫入字節/字符,不加換行符
}
public void println(String s) {
synchronized (this) {
print(s);
newLine(); // 關鍵:調用 newLine() 輸出平台相關換行符
}
}
private void newLine() {
try {
// Windows: \r\n, Linux/macOS: \n
write(lineSeparator); // lineSeparator = System.getProperty("line.separator")
} catch (IOException e) {
setTrouble();
}
}
關鍵點:println 內部調用 print + newLine(),newLine() 寫入系統屬性 line.separator(Windows \r\n、Unix \n),實現跨平台換行。
PrintStream 所有公共方法均 synchronized,println 鎖定範圍包含 print + newLine,理論上極微小增加鎖持有時間。println 多輸出 1-2 個換行字符,I/O 開銷可忽略。| 場景 | 錯誤寫法 | 正確寫法 | 說明 |
|---|---|---|---|
| 拼接輸出多變量 | print(a); print(b); println(c); | System.out.printf("%s%s%s%n", a, b, c); | printf/String.format 可控格式,%n 跨平台換行 | 調試輸出對象 | println(obj); (輸出 hashcode) | System.out.println(obj.toString()); 或重寫 toString() | 確保輸出有業務含義 |
| 高併發日誌 | 直接用 System.out.println | 用 Logger.info("msg {}", arg) | 日誌框架支持級別、異步、滾動、結構化 |
PrintStream:字節流,System.out 默認類型,自動刷新(autoFlush 構造器控制),不拋檢查異常。PrintWriter:字符流,可指定編碼,println 行為一致,但 autoFlush 僅在 println/printf/format 時觸發,print 不觸發。print:無換行,適合同行拼接輸出。println:自動換行,適合逐行輸出、日誌、調試。println = print + newLine(),newLine() 使用系統換行符 line.separator。