Философия Java

         

Особый случай RuntimeException


Первый пример в этой главе был:

if(t == null) throw new NullPointerException();

Это может быть немного пугающим: думать, что вы должны проверять на null каждую ссылку, передаваемую в метод (так как вы не можете знать, что при вызове была передана правильная ссылка). К счастью вам не нужно это, поскольку Java выполняет стандартную проверку во время выполнения за вас и, если вы вызываете метод для null ссылки, Java автоматически выбросит NullPointerException. Так что приведенную выше часть кода всегда излишняя.

Есть целая группа типов исключений, которые относятся к такой категории. Они всегда выбрасываются Java автоматически и вам не нужно включать их в вашу спецификацию исключений. Что достаточно удобно, что они все сгруппированы вместе и относятся к одному базовому классу, называемому RuntimeException, который является великолепным примером наследования: он основывает род типов, которые имеют одинаковые характеристики и одинаковы в поведении. Также вам никогда не нужно писать спецификацию исключения, объявляя, что метод может выбросить RuntimeException, так как это просто предполагается. Так как они указывают на ошибки, вы, фактически, никогда не выбрасываете RuntimeException — это делается автоматически. Если вы заставляете ваш код выполнять проверку на RuntimeExceptions, он может стать грязным. Хотя вы обычно не ловите RuntimeExceptions, в ваших собственных пакетах вы можете по выбору выбрасывать некоторые из RuntimeException.

Что случится, если вы не выбросите это исключение? Так как компилятор не заставляет включать спецификацию исключений для этого случая, достаточно правдоподобно, что RuntimeException могут принизывать насквозь ваш метод main( ) и не ловится. Чтобы увидеть, что случится в этом случае, попробуйте следующий пример:

//: c10:NeverCaught.java

// Игнорирование RuntimeExceptions.

public class NeverCaught { static void f() { throw new RuntimeException("From f()"); } static void g() { f(); } public static void main(String[] args) { g(); } } ///:~


Вы уже видели, что RuntimeException ( или любое, унаследованное от него) - это особый случай, так как компилятор не требует спецификации этих типов.

Вот что получится при выводе:

Exception in thread "main"

java.lang.RuntimeException: From f() at NeverCaught.f(NeverCaught.java:9) at NeverCaught.g(NeverCaught.java:12) at NeverCaught.main(NeverCaught.java:15)

Так что получим такой ответ: Если получаем RuntimeException, все пути ведут к выходу из main( ) без поимки, для такого исключения вызывается printStackTrace( ), и происходит выход из программы.

Не упускайте из виду, что вы можете только игнорировать RuntimeException в вашем коде, так как вся другая обработка внимательно ограничивается компилятором. Причина в том, что RuntimeException представляют ошибки программы:

  • Ошибка, которую вы не можете поймать (получение null ссылки, передаваемой в ваш метод клиентским программистом, например).


  • Ошибки, которые вы, как программист, должны проверять в вашем коде (такие как ArrayIndexOutOfBoundsException, где вы должны обращать внимание на размер массива).


  • Вы можете увидеть какая огромная выгода от этих исключений, так как они помогают процессу отладки.

    Интересно заметить, что вы не можете классифицировать обработку исключений Java, как инструмент с одним предназначением. Да, он предназначен для обработки этих надоедливых ошибок времени выполнения, которые будут случаться, потому что ограничения накладываются вне кода управления, но он также важен для определенных типов ошибок программирования, которые компилятор не может отследить.


    Содержание раздела