console.writeline và System.out.println


120

Sự khác biệt kỹ thuật chính xác giữa console.writelinevà là System.out.printlngì? Tôi biết rằng System.out.printlnghi vào đầu ra tiêu chuẩn nhưng điều này không giống với bảng điều khiển?

Tôi không hiểu đầy đủ các tài liệu cho console.writeline.



6
Console.WriteLine cũng không phải là một phương pháp java (nó là .net) ... nhưng tôi hiểu những gì bạn đang yêu cầu :)
robert_x44

Câu trả lời:


130

Dưới đây là những khác biệt chính giữa việc sử dụng System.out/ .err/.inSystem.console():

  • System.console()trả về null nếu ứng dụng của bạn không chạy trong thiết bị đầu cuối ( mặc dù bạn có thể xử lý điều này trong ứng dụng của mình )
  • System.console() cung cấp các phương pháp đọc mật khẩu mà không lặp lại các ký tự
  • System.outSystem.errsử dụng mã hóa nền tảng mặc định, trong khi các Consolephương thức đầu ra của lớp sử dụng mã hóa bảng điều khiển

Hành vi sau này có thể không rõ ràng ngay lập tức, nhưng mã như thế này có thể chứng minh sự khác biệt:

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);
    }
  }
}

Trên Windows XP của tôi có mã hóa hệ thống của windows-1252 và mã hóa bảng điều khiển mặc định của IBM850, mã này sẽ viết:

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

Lưu ý rằng hành vi này phụ thuộc vào việc mã hóa bảng điều khiển được đặt thành một mã hóa khác với mã hóa hệ thống. Đây là hành vi mặc định trên Windows vì nhiều lý do lịch sử.


Bạn có thể lấy một ví dụ về việc không chạy trong một thiết bị đầu cuối không?
Chao

@Richard, nếu bạn nhấn chạy từ IDE hoặc nếu bạn khởi chạy một jar thực thi từ GUI.
aioobe

15

Về cơ bản, chúng giống nhau, nếu chương trình của bạn được chạy từ một lời nhắc tương tác và bạn chưa chuyển hướng stdin hoặc stdout:

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

kết quả trong:

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

Lý do Consoletồn tại là để cung cấp các tính năng hữu ích trong trường hợp cụ thể mà bạn đang chạy từ một dòng lệnh tương tác:

  • nhập mật khẩu an toàn (khó thực hiện trên nhiều nền tảng)
  • đồng bộ hóa (nhiều luồng có thể nhắc nhập và Consolesẽ xếp chúng vào hàng một cách dễ dàng, trong khi nếu bạn sử dụng System.in/out thì tất cả các lời nhắc sẽ xuất hiện đồng thời).

Lưu ý ở trên rằng chuyển hướng thậm chí một trong các luồng dẫn đến System.console()trả về null; một điều khó chịu khác là thường không có Consoleđối tượng nào có sẵn khi sinh ra từ một chương trình khác như Eclipse hoặc Maven.


7

Trước tiên, tôi e rằng câu hỏi của bạn có một chút sai lầm. Không có phương thức writeline trong Bảng điều khiển lớp. Thay vào đó, bảng điều khiển lớp cung cấp trình viết phương thức () trả về PrintWriter. Người viết bản in này có println ().

Bây giờ sự khác biệt giữa

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

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

Nếu bạn chạy ứng dụng của mình từ dòng lệnh, tôi nghĩ không có sự khác biệt. Nhưng nếu bảng điều khiển không khả dụng, System.console () trả về null trong khi System.out vẫn tồn tại. Điều này có thể xảy ra nếu bạn gọi ứng dụng của mình và thực hiện chuyển hướng STDOUT đến tệp.

Đây là một ví dụ mà tôi vừa thực hiện.

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");
    }
}

Khi tôi chạy ứng dụng từ dấu nhắc lệnh, tôi nhận được những điều sau:

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

nhưng khi tôi chuyển hướng STDOUT đến tệp ...

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

Dòng 8 là console.writer().println().

Đây là nội dung của / tmp / test

console=null

Tôi hy vọng những lời giải thích của tôi sẽ giúp ích.


Để làm cho mã hiển thị dưới dạng khối mã, hãy thụt lề mỗi dòng với bốn dấu cách. (Tuy nhiên, tôi vừa làm điều đó cho bạn.)
BoltClock

Tuy nhiên, có một Console.printf và Console.format, cả hai đều viết trực tiếp, không cần trích xuất PrintWriter can thiệp. Weird :)
Toby Eggitt

3

Không có Console.writelinetrong Java. Của nó trong .NET.

Bảng điều khiển và tiêu chuẩn ra không giống nhau. Nếu bạn đọc trang Javadoc mà bạn đã đề cập , bạn sẽ thấy rằng một ứng dụng chỉ có thể có quyền truy cập vào bảng điều khiển nếu nó được gọi từ dòng lệnh và đầu ra không được chuyển hướng như thế này

java -jar MyApp.jar > MyApp.log

Những trường hợp như vậy khác được đề cập trong câu trả lời của SimonJ, mặc dù anh ấy đã bỏ qua điểm không có Console.writeline.


Yup - Tôi đã tìm ra trình biên dịch của ziggy (hoặc Javadocs) có thể làm công việc đó cho tôi :)
SimonJ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.