console.writeline และ System.out.println


120

อะไรคือความแตกต่างทางเทคนิคระหว่างconsole.writelineและSystem.out.println? ฉันรู้ว่าSystem.out.printlnเขียนไปยังเอาต์พุตมาตรฐาน แต่นี่ไม่ใช่สิ่งเดียวกับคอนโซลหรือไม่

ฉันไม่เข้าใจเอกสารสำหรับconsole.writeline.



6
console.writeline ไม่ใช่เมธอด java (มันคือ. net) ... แต่ฉันเข้าใจว่าคุณกำลังถามอะไร :)
robert_x44

คำตอบ:


130

ความแตกต่างหลักระหว่างการใช้System.out/ .err/.inและSystem.console():

พฤติกรรมหลังนี้อาจไม่ชัดเจนในทันที แต่โค้ดเช่นนี้สามารถแสดงให้เห็นถึงความแตกต่าง:

public class ConsoleDemo {
  public static void main(String[] args) {
    String[] data = { "\u250C\u2500\u2500\u2500\u2500\u2500\u2510", 
        "\u2502Hello\u2502",
        "\u2514\u2500\u2500\u2500\u2500\u2500\u2518" };
    for (String s : data) {
      System.out.println(s);
    }
    for (String s : data) {
      System.console().writer().println(s);
    }
  }
}

บน Windows XP ของฉันซึ่งมีการเข้ารหัสระบบของ windows-1252 และการเข้ารหัสคอนโซลดีฟอลต์ของ IBM850 รหัสนี้จะเขียน:

???????
?Hello?
???????
┌─────┐
Hello
└─────┘

โปรดทราบว่าลักษณะการทำงานนี้ขึ้นอยู่กับการเข้ารหัสคอนโซลที่ตั้งค่าเป็นการเข้ารหัสอื่นสำหรับการเข้ารหัสระบบ นี่เป็นลักษณะการทำงานเริ่มต้นบน Windows เนื่องจากเหตุผลทางประวัติศาสตร์หลายประการ


ขอตัวอย่างการไม่ทำงานในเทอร์มินัลได้ไหม
เจ้า

@Richard ถ้าคุณกด run จาก IDE หรือเปิด jar ที่เรียกใช้งานได้จาก GUI
aioobe

15

โดยพื้นฐานแล้วจะเหมือนกันหากโปรแกรมของคุณเรียกใช้จากพรอมต์แบบโต้ตอบและคุณไม่ได้เปลี่ยนเส้นทาง stdin หรือ stdout:

public class ConsoleTest {
    public static void main(String[] args) {
        System.out.println("Console is: " + System.console());
    }
}

ผลลัพธ์ใน:

$ java ConsoleTest
Console is: java.io.Console@2747ee05
$ java ConsoleTest </dev/null
Console is: null
$ java ConsoleTest | cat
Console is: null

เหตุผลที่Consoleมีอยู่คือเพื่อให้คุณสมบัติที่มีประโยชน์ในกรณีเฉพาะที่คุณกำลังเรียกใช้จากบรรทัดคำสั่งแบบโต้ตอบ:

  • การป้อนรหัสผ่านที่ปลอดภัย (ข้ามแพลตฟอร์มได้ยาก)
  • การซิงโครไนซ์ (หลายเธรดสามารถแจ้งให้ป้อนข้อมูลและConsoleจะจัดคิวให้เป็นอย่างดีในขณะที่หากคุณใช้ System.in/out การแจ้งทั้งหมดจะปรากฏขึ้นพร้อมกัน)

แจ้งให้ทราบข้างต้นว่าแม้เปลี่ยนเส้นทางหนึ่งของลำธารผลในการSystem.console()กลับมาnull; การระคายเคืองอีกประการหนึ่งคือมักจะไม่มีConsoleวัตถุใดๆ เมื่อเกิดจากโปรแกรมอื่นเช่น Eclipse หรือ Maven


7

ก่อนอื่นฉันกลัวว่าคำถามของคุณจะมีข้อผิดพลาดเล็กน้อย ไม่มีวิธีเขียนเมธอดในคอนโซลคลาส แทนที่คลาส Console จะจัดเตรียม method writer () ที่ส่งคืน PrintWriter เครื่องเขียนนี้มี println ()

ตอนนี้อะไรคือความแตกต่างระหว่าง

System.console().writer().println("hello from console");

และ

System.out.println("hello system out");

หากคุณเรียกใช้แอปพลิเคชันจากบรรทัดคำสั่งฉันคิดว่าไม่มีความแตกต่าง แต่ถ้าคอนโซลไม่พร้อมใช้งาน System.console () จะคืนค่า null ในขณะที่ System.out ยังคงมีอยู่ สิ่งนี้อาจเกิดขึ้นหากคุณเรียกใช้แอปพลิเคชันของคุณและทำการเปลี่ยนเส้นทางของ STDOUT ไปยังไฟล์

นี่คือตัวอย่างที่ฉันเพิ่งใช้

import java.io.Console;


public class TestConsole {
    public static void main(String[] args) {
        Console console = System.console();
        System.out.println("console=" + console);
        console.writer().println("hello from console");
    }
}

เมื่อฉันเรียกใช้แอปพลิเคชันจากพรอมต์คำสั่งฉันได้รับสิ่งต่อไปนี้:

$ java TestConsole
console=java.io.Console@93dcd
hello from console

แต่เมื่อฉันเปลี่ยนเส้นทาง STDOUT ไปยังไฟล์ ...

$ java TestConsole >/tmp/test
Exception in thread "main" java.lang.NullPointerException
        at TestConsole.main(TestConsole.java:8)

บรรทัดที่ 8 คือconsole.writer().println().

นี่คือเนื้อหาของ / tmp / test

console=null

ฉันหวังว่าคำอธิบายของฉันจะช่วยได้


หากต้องการทำให้โค้ดแสดงเป็นบล็อกโค้ดให้เยื้องแต่ละบรรทัดด้วยช่องว่างสี่ช่อง (ฉันเพิ่งทำเพื่อคุณ)
BoltClock

อย่างไรก็ตามมี Console.printf และ Console.format ซึ่งทั้งสองแบบนี้เขียนโดยตรงโดยไม่จำเป็นต้องแยก PrintWriter ที่แทรกแซง แปลก :)
Toby Eggitt

3

ไม่มีConsole.writelineใน Java ใน. NET

คอนโซลและมาตรฐานไม่เหมือนกัน หากคุณอ่านหน้า Javadoc ที่คุณกล่าวถึงคุณจะเห็นว่าแอปพลิเคชันสามารถเข้าถึงคอนโซลได้ก็ต่อเมื่อมีการเรียกใช้จากบรรทัดคำสั่งและผลลัพธ์จะไม่ถูกเปลี่ยนทิศทางเช่นนี้

java -jar MyApp.jar > MyApp.log

กรณีดังกล่าวได้รับความคุ้มครองอื่น ๆ ในคำตอบของ SimonJ Console.writelineแม้ว่าเขาจะพลาดจุดที่ไม่มี


ใช่ - ฉันคิดว่าคอมไพเลอร์ของ ziggy (หรือ Javadocs) สามารถทำงานนั้นให้ฉันได้ :)
SimonJ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.