2014-05-22 16 views
8

Câu hỏi của tôi có liên quan đến hành vi cú pháp của khối try catchBắt ngoại lệ không được ném cục bộ?

rỗng khối try với một nắm bắt như thế này

void fun() { 
    try {} 
    catch(Exception e) {} 
} 

hoặc

try {} 
catch(ArrayIndexOutOfBoundsException e) {} 

biên dịch tốt nhưng trình biên dịch phàn nàn với

try {} 
catch(IOException e) {} 

Tại sao trình biên dịch tất cả ow bắt bất cứ thứ gì có kiểu Exception hoặc RuntimeException trong khi nó phàn nàn về mã không truy cập được với các ngoại lệ đã kiểm tra? Có phải vì mã JVM có thể ném các loại đó không? Làm thế nào có thể JVM có thể ném ArrayIndexOutOfBoundsException trong một khối thử rỗng?

Trả lời

10

Khối trống là trường hợp đặc biệt không được JLS xử lý đặc biệt. Yêu cầu JLS yêu cầu là nếu bạn bắt ngoại lệ được kiểm tra, mã trong khối try phải có khả năng ném ngoại lệ đó (tức là nó ném trực tiếp hoặc gọi phương thức được khai báo có thể ném nó) .

Nói cách khác, có kiểm tra độ chính xác cụ thể cho các ngoại lệ đã kiểm tra, nhưng không dành cho tất cả ngoại lệ với các trường hợp ngoại lệ được kiểm tra để được xem xét thêm.

này được mô tả trong JLS 14.21, và cụ thể là:

Đó là một lỗi thời gian biên dịch nếu một tuyên bố không thể được thực hiện bởi vì nó là không thể truy cập.

...

Một khối catch C có thể truy cập khi và chỉ khi cả những điều sau đây là đúng:

  • Hoặc là loại tham số C 's là một loại ngoại lệ được kiểm soát hoặc Exception hoặc một superclass của Exception, hoặc một số biểu thức hoặc ném tuyên bố trong khối thử là có thể truy cập và có thể ném một ngoại lệ kiểm tra có loại được gán cho loại tham số C của. (Một biểu thức có thể truy cập được iff tuyên bố trong cùng chứa nó có thể truy cập được.)

    Xem §15.6 để hoàn thành biểu thức bình thường và đột ngột.

  • Không có khối catch nào trước đó A trong câu lệnh thử sao cho kiểu tham số C giống như hoặc một lớp con của loại tham số A.

nhấn mạnh thêm: nó cho thấy rằng nếu bạn đang bắt một loại ngoại lệ được kiểm soát, khối catch có thể truy cập.

Cá nhân tôi thấy từ ngữ hơi khó hiểu.Hơi reworded, điểm viên đạn đầu tiên chỉ nói rằng mệnh đề catch phải bắt một trong số:

  • Một ngoại lệ không được kiểm soát
  • Exception
  • Throwable (đó là lớp cha duy nhất của Exception khác hơn Object, mà bạn có thể 't catch)
  • một ngoại lệ kiểm tra rằng khối try có thể ném

các bul thứ hai hãy bảo vệ chống lại một khối catch không thể truy cập được vì trước đó catch trong đó try. Ví dụ:

try { 
    whatever(); 
} catch (Exception e) { 
    handleException(e); 
} catch (NullPointerException e) { 
    // This block is unreachable, because a NullPointerException is an 
    // Exception and will thus be handled by the previous catch block. 
    handleNpe(e); 
} 
Các vấn đề liên quan