Изменения

Перейти к: навигация, поиск

Обработка ошибок и исключения

2356 байт добавлено, 00:40, 2 марта 2019
Классификация исключений
}
<font color=gray>//...</font>
<font color=navy>'''if'''</font> (Math.''abs''(b) < <font color=purple>'''EPS'''</font>) {
<font color=navy>'''return null'''</font>;
} <font color=navy>'''else'''</font> {
}
<font color=gray>//...</font>
<font color=navy>'''if'''</font> (Math.''abs''(b) < <font color=purple>'''EPS'''</font>) {
<font color=navy>'''return'''</font> divisionByZero();
} <font color=navy>'''else'''</font> {
==Классификация исключений==
Класс Java <code>Throwable</code> описывает все, что может быть брошено как исключение. Наследеники <code>Throwable</code> - <code>EcxeptionException</code> и <code>Error</code> - основные типы исключений. Также <code>RuntimeException</code>, унаследованный от <code>Exception</code>, является существенным классом.
[[Файл:Exceptions.png|400px|thumb|right|Иерархия стандартных исключений]]
===Проверяемые исключения===
Чтобы сгенерировать исключение используется ключевое слово <code>throw</code>. Как и любой объект в Java, исключения создаются с помощью <code>new</code>.
<font color=navy>'''if '''</font> (t == <font color=navy>'''null'''</font>) { <font color=navy>'''throw new '''</font> NullPointerException(<font color=green>"t = null"</font>);
}
Как и было сказано раньше, определение метода должно содержать список всех проверяемых исключений, которые метод может бросить. Также можно написать более общий класс, среди наследников которого есть эти исключения.
<font color=navy>'''void '''</font> f() <font color=navy>'''throws '''</font> InterruptedException, IOException { <font color=gray>//...</font>
===try-catch-finally===
Код, который может бросить исключения оборачивается в <code>try</code>-блок, после которого идут блоки <code>catch</code> и <code>finally</code> (Последний Один из них может быть опущен).
<font color=navy>'''try '''</font> { <font color=gray>// Код, который может сгенерировать исключение</font>
}
Сразу после блока проверки следуют после обработчики исключений, которые объявляются ключевым словом catch.
<font color=navy>'''try '''</font> { <font color=gray>// Код, который может сгенерировать исключение</font> } <font color=navy>'''catch'''</font>(Type1 id1) { <font color=gray>// Обработка исключения Type1</font> } <font color=navy>'''catch'''</font>(Type2 id2) { <font color=gray>// Обработка исключения Type2</font>
}
Блок <code>finally</code> удобен для закрытия файлов и освобождения любых других ресурсов. Код в блоке <code>finally</code> должен быть максимально простым. Если внутри блока <code>finally</code> будет брошено какое-либо исключение или просто встретится оператор <code>return</code>, брошенное в блоке <code>try</code> исключение (если таковое было брошено) будет забыто.
<font color=navy>'''<tt>import</tt>'''</font> java.io.IOException;
<font color=navy>'''<tt>public class ExceptionTest'''</tt> </font> ExceptionTest {
<font color=navy>'''<tt>public static void</tt>'''</font> main(<tt>String[]</tt> args) { <font color=navy>'''<tt>try</tt>'''</font> { <font color=navy>'''<tt>try</tt>'''</font> { <font color=navy>'''<tt>throw new </tt>''' </font>Exception(<font color=green>"a")</ttfont>); } <font color=navy>'''<tt>finally</tt>'''</font> { <font color=navy>'''<tt>throw new IOException</tt>'''</font> IOException(<font color=green>"b"</font>);
}
} <font color=navy>'''<tt>catch '''</tt></font> (IOException ex)</tt> { System.<font color=purple>'''''err'''''</font>.println(ex.getMessage()); } <font color=navy>'''<tt>catch '''</tt></font> (Exception ex)</tt> { System.<font color=purple>'''''err'''''</font>.println(ex.getMessage());
}
}
Чтобы определить собственное проверяемое исключение, необходимо создать наследника класса <code>java.lang.Exception</code>. Желательно, чтобы у исключения был конструкор, которому можно передать сообщение:
<font color=navy>'''public class '''</font> FooException <font color=navy>'''extends '''</font> Exception { <font color=navy>'''public '''</font> FooException() { <font color=navy>'''super'''</font>();
}
<font color=navy>'''public '''</font> FooException(String message) { <font color=navy>'''super'''</font>(message);
}
<font color=navy>'''public '''</font> FooException(String message, Throwable cause) { <font color=navy>'''super'''</font>(message, cause);
}
<font color=navy>'''public '''</font> FooException(Throwable cause) { <font color=navy>'''super'''</font>(cause);
}
}
* обработка нескольких типов исключений в одном <code>catch</code>-блоке:
<code><font color=navy>'''catch'''</font></code> (<tt>IOException</tt> | <tt>SQLException</tt> ex) {...}
В таких случаях параметры неявно являются <code>final</code>, поэтому нельзя присвоить им другое значение в блоке <code>catch</code>.
* <code>Try</code> с ресурсами позволяет прямо в <code>try</code>-блоке объявлять необходимые ресурсы, которые по завершению блока будут корректно закрыты (с помощью метода <code>close()</code>). Любой объект реализующий <code>java.lang.AutoCloseable</code> может быть использован как ресурс.
<tt><font color=navy>'''static '''</font> String</tt> readFirstLineFromFile(String path) <tt><font color=navy>'''throws '''</font> IOException</tt> { <tt><font color=navy>'''try'''</font></tt> (<tt>BufferedReader</tt> br = <tt><font color=navy>'''new '''</font> BufferedReader(<font color=navy>'''new '''</font> FileReader</tt>(path))) { <tt><font color=navy>'''return'''</font></tt> br.readLine();
}
}
Можно объявлять несколько ресурсов, разделяя их точкой с запятой:
<font color=navy>'''public static void '''</font> viewTable(Connection con) throws SQLException {
String query = <font color=green>"select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES"</font>;
<font color=navy>'''try '''</font> (Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(query)) { <font color=gray>//Work with Statement and ResultSet</font> } <font color=navy>'''catch '''</font> (SQLException e) {
e.printStackTrace;
}
Компилятор Java SE 7 тщательнее анализирует перебрасываемые исключения. Рассмотрим следующий пример:
<font color=navy>'''static class '''</font> FirstException <font color=navy>'''extends '''</font> Exception { } <font color=navy>'''static class '''</font> SecondException <font color=navy>'''extends '''</font> Exception { }
<font color=navy>'''public void '''</font> rethrowException(String exceptionName) <font color=navy>'''throws '''</font> Exception { <font color=navy>'''try '''</font> { <font color=navy>'''if '''</font> (exceptionName<font color=green>"First"</font>.equals("First"exceptionName)) { <font color=navy>'''throw new '''</font> FirstException(); } <font color=navy>'''else '''</font> { <font color=navy>'''throw new '''</font> SecondException();
}
} <font color=navy>'''catch '''</font> (Exception ex) { <font color=navy>'''throw '''</font> e;
}
}
В примере <code>try</code>-блок может бросить либо <code>FirstException</code>, либо <code>SecondException</code>. В версиях до Java SE 7 невозможно указать эти исключения в декларации метода, потому что <code>catch</code>-блок перебрасывает исключение <code>ex</code>, тип которого - <code>Exception</code>.
В Java SE 7 вы можете указать, что метод <code>rethrowException</code> бросает только <code>FirstException</code> и <code>SecondException</code>. Компилятор определит, что исключение <code>Exception ex</code> могло возникнуть только в <code>try</code>-блоке, в котором может быть брошено <code>FirstException</code> или <code>SecondException</code>. Даже если тип параметра <code>catch</code> - <code>Exception</code>, компилятор определит , что это экземпляр либо <code>FirstException</code>, либо <code>SecondException</code>:
<font color=navy>'''public void '''</font> rethrowException(String exceptionName) <font color=navy>'''throws '''</font> FirstException, SecondException { <font color=navy>'''try '''</font> { <font color=gray>// ...</font> } <font color=navy>'''catch '''</font> (Exception e) { <font color=navy>'''throw '''</font> e;
}
}
* <code>IllegalArgumentException</code> используется для того, чтобы избежать передачи некорректных значений аргументов. Например:
<tt><font color=navy>'''public void'''</font></tt> f(<tt>Object</tt> a) { <tt><font color=navy>'''if'''</font></tt> (a == <tt><font color=navy>'''null'''</font></tt>) { <tt><font color=navy>'''throw new NullPointerException'''</font> IllegalArgumentException</tt>(<font color=green>"a must not be null"</font>);
}
}
* Слабые гарантии (''weak exceptional safety''). Если объект бросил исключение, то он находится в корректном состоянии, и все инварианты сохранены. Рассмотрим пример:
<font color=navy>'''class '''</font> Interval { <font color=gray>//invariant: left <= right</font>
double left;
double right;
<font color=gray>//...</font>
}
Анонимный участник

Навигация