2011-08-07 40 views
5

Trong chương trình này, chuỗi thứ ba không bao giờ được in. Tại sao?Tại sao một PrintWriter cục bộ can thiệp với một PrintWriter cục bộ khác?

(chương trình Java này được chạy trên Eclipse Indigo trên Ubuntu 10.10.)

import java.io.PrintWriter; 

public class Tester 
{ 
    static void nested() 
    { 
     PrintWriter object2 = new PrintWriter(System.out, true); 
     object2.println("second"); 
     object2.close(); // delete this line to make all strings print 
    } 

    public static void main(String[] args) 
    { 
     PrintWriter object1 = new PrintWriter(System.out, true); 
     object1.println("first"); 
     Tester.nested(); 
     object1.println("third"); 
     object1.close(); 
    } 
} 

Trả lời

4

Bằng cách đóng lồng nhau PrintWriter, bạn cũng đóng nhúng System.out suối, mà dường như ngăn chặn hơn nữa viết cho nó (mặc dù tôi sẽ mong đợi một ngoại lệ thực sự thay vì nuốt đầu ra).

Vì vậy, toàn bộ vấn đề có thể được giảm xuống còn:

public class Tester { 

    public static void main(String[] args) {   
     System.out.println("first"); 
     System.out.close(); 
     System.out.println("second");   
    } 
} 

này quá không in nữa sau "đầu tiên", nhưng cũng không ném một ngoại lệ. Một phiên gỡ lỗi rất nhanh cho thấy có một lời gọi đến một hàm gốc của Sun, một chút khó khăn hơn để gỡ lỗi.

Update *

Đây là thủ phạm: System.out là loại java.io.PrintStream và nó chứa sau đáng yêu phương pháp:

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

Phương pháp ensureOpen() thực sự ném một ngoại lệ, nhưng nó nuốt ở đây và cờ trouble được đặt (một mẫu chống nổi tiếng). Điều này do đó âm thầm bỏ qua thêm viết cho dòng đóng.

1

Từ các tài liệu của close() nó nói

Đóng stream và phiên bản bất kỳ tài nguyên hệ thống liên quan đến nó. Đóng luồng đã đóng trước đây không có hiệu lực

Vì vậy, tôi đoán là nó đang phát hành System.out và do đó không thể sử dụng lại được nữa. Ngoài ra, tôi đã thêm một dòng System.out.println("Finished"); ở cuối và nó không xuất ra bất cứ điều gì nếu một đóng đã được gọi trên System.out trong mã. Hãy dùng thử.

Các vấn đề liên quan