2013-07-31 39 views
5

tôi đã chạy một số thí nghiệm đơn giản như thế này:Việc ném một ngoại lệ có thay đổi trạng thái của nó không?

public static void main(String[] args) { 
    try { 
     NullPointerException n = new NullPointerException(); 
     System.out.println(Lists.newArrayList(n.getStackTrace())); 
     n.printStackTrace(); 
     System.out.println(Lists.newArrayList(n.getStackTrace())); 
     throw n; 
    } catch (NullPointerException e) { 
     e.printStackTrace(); 
     System.out.println(Lists.newArrayList(e.getStackTrace())); 
    } 
} 

và nhận được kết quả như thế này:

java.lang.NullPointerException 
    at MyTest.main(MyTest.java:231) 
java.lang.NullPointerException 
    at MyTest.main(MyTest.java:231) 
[MyTest.main(AbstractScannerTest.java:231)] 
[MyTest.main(AbstractScannerTest.java:231)] 
[MyTest.main(AbstractScannerTest.java:231)] 

Nhưng tôi tự hỏi, nếu bất cứ điều gì được thực hiện với một ngoại lệ khi nó được ném. Đây là một câu hỏi chủ yếu về mặt học thuật, mặc dù nó có thể có liên quan trong một số trường hợp nhất định nếu một ngoại lệ là một phần của một API và có thể hoặc có thể không bị ném khi được cung cấp cho việc triển khai.

+0

Để có một dấu vết ngăn xếp đầy đủ và có thể thêm một chút thông tin khi in lỗi, bạn chỉ có thể thực hiện 'System.out.println (e);' hoặc 'System.out.println (" báo cáo lỗi ", e); 'và nó sẽ in toàn bộ stacktrace. Chỉ cần một đầu lên. – sparks

+3

'printStackTrace' sử dụng' System.err' không phải 'System.out'. Để làm cho kết quả của bạn trông như mong đợi, sử dụng 'printStacktrace (System.out)'. –

+1

Lưu ý rằng, trong Java, dấu vết ngăn xếp ngoại lệ được thực hiện khi ngoại lệ được tạo ra, không phải khi nó được tạo ra. –

Trả lời

2

Không, đối tượng Throwable bản thân nó không bị sửa đổi bởi hoạt động throw; nó chỉ đơn giản là thông qua ngăn xếp cuộc gọi tương tự như đối số của phương thức sẽ như thế nào. Throwable s thường được thiết kế để trở thành đối tượng bất biến và không có bộ định vị, mặc dù một số hỗ trợ sửa đổi dấu vết ngăn xếp sao cho RPC hoặc khung tương tự có thể đảm bảo rằng thông tin theo dõi lỗi thích hợp được bao gồm. Điều đó nói rằng, một Throwable là một đối tượng như bất kỳ khác, và bạn có thể viết một lớp học Throwable có phương pháp đột biến được gọi là trong một khối catch, mặc dù đó không phải là bình thường.

+1

Thực ra, Throwable có một số phương pháp sẽ biến đổi nó. Đáng chú ý nhất sẽ là fillInStackTrace ghi đè lên dấu vết ngăn xếp được chụp khi Throwable được tạo ra. –

+0

Bạn nói đúng, tôi đã viết rất tệ. 'fillInStackTrace', như trường hợp ngoại lệ mà tôi chú ý, làm cho' Throwable' có thể thay đổi được, nhưng hầu hết các lớp ngoại lệ không có mutators khác, và phương thức đó có thể không thực sự sửa đổi stack trace nếu 'writableStackTrace' là' false'. – chrylis

1

Tôi không biết gì cả. Hai điều quan trọng là

  • khi Throwable được tạo ra
  • khi getStackTrace() được gọi nó populates mảng thực tế (cho đến lúc đó nó được lưu trữ ra khỏi đống)
Các vấn đề liên quan