Зачем кидать исключения java. Java: Операторы throw и throws

Зачем кидать исключения java. Java: Операторы throw и throws


2. Какова иерархия исключений.
3. Можно/нужно ли обрабатывать ошибки jvm?
4. Какие существуют способы обработки исключений?
5. О чем говорит ключевое слово throws?
6. В чем особенность блока finally? Всегда ли он исполняется?
7. Может ли не быть ни одного блока catch при отлавливании исключений?
8. Могли бы вы придумать ситуацию, когда блок finally не будет выполнен?
9. Может ли один блок catch отлавливать несколько исключений (с одной и разных веток наследований)?
10. Что вы знаете об обрабатываемых и не обрабатываемых (checked/unchecked) исключениях?
11. В чем особенность RuntimeException?
12. Как написать собственное (“пользовательское”) исключение? Какими мотивами вы будете руководствоваться при выборе типа исключения: checked/unchecked?
13. Какой оператор позволяет принудительно выбросить исключение?
14. Есть ли дополнительные условия к методу, который потенциально может выбросить исключение?
15. Может ли метод main выбросить исключение во вне и если да, то где будет происходить обработка данного исключения?
16. Если оператор return содержится и в блоке catch и в finally, какой из них “главнее”?
17. Что вы знаете о OutOfMemoryError?
18. Что вы знаете о SQLException? К какому типу checked или unchecked оно относится, почему?
19. Что такое Error? В каком случае используется Error. Приведите пример Error’а.
20. Какая конструкция используется в Java для обработки исключений?
21. Предположим, есть блок try-finally. В блоке try возникло исключение и выполнение переместилось в блок finally. В блоке finally тоже возникло исключение. Какое из двух исключений “выпадет” из блока try-finally? Что случится со вторым исключением?
22. Предположим, есть метод, который может выбросить IOException и FileNotFoundException в какой последовательности должны идти блоки catch? Сколько блоков catch будет выполнено?

Ответы

1. Дайте определение понятию “исключение”

Исключение — это проблема(ошибка) возникающая во время выполнения программы. Исключения могут возникать во многих случаях, например:

  1. Пользователь ввел некорректные данные.
  2. Файл, к которому обращается программа, не найден.
  3. Сетевое соединение с сервером было утеряно во время передачи данных. И т.д.

Все исключения в Java являются объектами. Поэтому они могут порождаться не только автоматически при возникновении исключительной ситуации, но и создаваться самим разработчиком.

2. Какова иерархия исключений.

Исключения делятся на несколько классов, но все они имеют общего предка - класс Throwable. Его потомками являются подклассы Exception и Error.

Исключения (Exceptions) являются результатом проблем в программе, которые в принципе решаемые и предсказуемые. Например, произошло деление на ноль в целых числах.

Ошибки (Errors) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует пытаться обрабатывать в собственной программе, поскольку они связаны с проблемами уровня JVM. Например, исключения такого рода возникают, если закончилась память, доступная виртуальной машине. Программа дополнительную память всё равно не сможет обеспечить для JVM.

В Java все исключения делятся на два типа: контролируемые исключения (checked) и неконтролируемые исключения (unchecked), к которым относятся ошибки (Errors) и исключения времени выполнения (RuntimeExceptions, потомок класса Exception).

Контролируемые исключения представляют собой ошибки, которые можно и нужно обрабатывать в программе, к этому типу относятся все потомки класса Exception (но не RuntimeException).

3. Можно/нужно ли обрабатывать ошибки jvm?

Обрабатывать можно, но делать этого не стоит. Разработчику не предоставлены инструменты для обработки ошибок системы и виртуальной машины.

4. Какие существуют способы обработки исключений?

В Java есть пять ключевых слов для работы с исключениями:

  1. try — данное ключевое слово используется для отметки начала блока кода, который потенциально может привести к ошибке.
  2. catch — ключевое слово для отметки начала блока кода, предназначенного для перехвата и обработки исключений.
  3. finally — ключевое слово для отметки начала блока кода, которой является дополнительным. Этот блок помещается после последнего блока ‘catch’. Управление обычно передаётся в блок ‘finally’ в любом случае.
  4. throw — служит для генерации исключений.
  5. throws

Общий вид конструкции для «поимки» исключительной ситуации выглядит следующим образом:

Подробнее http://www.quizful.net/post/java-exceptions

5. О чем говорит ключевое слово throws?

throws — ключевое слово, которое прописывается в сигнатуре метода, и обозначающее что метод потенциально может выбросить исключение с указанным типом.

6. В чем особенность блока finally? Всегда ли он исполняется?

Когда исключение передано, выполнение метода направляется по нелинейному пути. Это может стать источником проблем. Например, при входе метод открывает файл и закрывает при выходе. Чтобы закрытие файла не было пропущено из-за обработки исключения, был предложен механизм finally .

Ключевое слово finally создаёт блок кода, который будет выполнен после завершения блока try/catch , но перед кодом, следующим за ним. Блок будет выполнен, независимо от того, передано исключение или нет. Оператор finally не обязателен, однако каждый оператор try требует наличия либо catch , либо finally . Код в блоке finally будет выполнен всегда .

7. Может ли не быть ни одного блока catch при отлавливании исключений?

Такая запись допустима, если имеется связка try{} finally {}. Но смысла в такой записи не так много, всё же лучше иметь блок catch в котором будет обрабатываться необходимое исключение.

String x = "z"; try { x="234"; } finally { x = "Finally"; }

String x = "z" ;

try {

x = "234" ;

} finally {

x = "Finally" ;

8. Могли бы вы придумать ситуацию, когда блок finally не будет выполнен?

Блок finally выполняется не всегда, например в такой ситуации:

try { System.exit(0); } catch(Exception e) { e.printStackTrace(); } finally { }

try {

System . exit (0 ) ;

} catch (Exception e ) {

e . printStackTrace () ;

} finally { }

Здесь finally недостижим, так как происходит системный выход из программы. Общими словами: когда jvm умирает, ей не до finally (отсюда можете придумать другие примеры как убить jvm и ответить на вопрос в заголовке).

9. Может ли один блок catch отлавливать несколько исключений (с одной и разных веток наследований)?

В Java 7 стала доступна новая конструкция, с помощью которой можно перехватывать несколько исключений одним блоком catch:

try { ... } catch(IOException | SQLException ex) { logger.log(ex); throw ex; }

try {

. . .

} catch (IOException | SQLException ex ) {

logger . log (ex ) ;

throw ex ;

10. Что вы знаете об обрабатываемых и не обрабатываемых (checked/unchecked) исключениях?

Все исключительные ситуации делятся на «проверяемые» (checked) и «непроверяемые» (unchecked) (смотрите картинку в начале статьи). Это свойство присуще «корневищу» (Throwable, Error, Exception, RuntimeException) и передается по наследству. Никак не видимо в исходном коде класса исключения.
В дальнейших примерах просто учтите, что- Throwable и Exception и все их наследники (за исключением наследников Error-а и RuntimeException-а) - checked
- Error и RuntimeException и все их наследники - unchecked
checked exception = проверяемое исключение, проверяемое компилятором.

Тема достаточно обширная для того, чтобы уместить ее в одном ответе. К примеру, можно разобрать примеры Головача: http://habrahabr.ru/company/golovachcourses/blog/225585/

И еще с quizful.net

1. Checked исключения, это те, которые должны обрабатываться блоком catch или описываться в сигнатуре метода. Unchecked могут не обрабатываться и не быть описанными.
2. Unchecked исключения в Java — наследованные от RuntimeException, checked — от Exception (не включая unchecked).

Checked исключения отличаются от Unchecked исключения в Java, тем что:
1)Наличие\обработка Checked исключения проверяются на этапе компиляции . Наличие\обработка Unchecked исключения происходит на этапе выполнения .

11. В чем особенность RuntimeException?

public class RuntimeException extends Exception — базовый класс для ошибок во время выполнения. Относится к необрабатываемым исключениям (uncatched\unchecked). Как сказано в описании класса — это суперкласс, исключения которого могут быть выброшены во время нормальной работы JVM.

12. Как написать собственное (“пользовательское”) исключение? Какими мотивами вы будете руководствоваться при выборе типа исключения: checked/unchecked?

Необходимо унаследоваться от базового класса требуемого типа исключений (например от Exception или RuntimeException).

public class ExcClass extends Exception { private String someString; public ExcClass (String string) { this.someString = string; System.out.println("Exception ExcClass"); } public void myOwnExceptionMsg() { System.err.println("This is exception massage for string: " + someString); } } public class TestExc { public static void main(String args) { try { String s = "SomeString"; throw new ExcClass(s); } catch (ExcClass ex) { ex.myOwnExceptionMsg(); } } } //Вывод Exception ExcClass This is exception massage for string: SomeString

public class ExcClass extends Exception {

private String someString ;

public ExcClass (String string ) {

this . someString = string ;

System . out . println ("Exception ExcClass" ) ;

public void myOwnExceptionMsg () {

System . err . println ("This is exception massage for string: " + someString ) ;

public class TestExc {

try {

String s = "SomeString" ;

throw new ExcClass (s ) ;

} catch (ExcClass ex ) {

ex . myOwnExceptionMsg () ;

//Вывод

Exception ExcClass

This is exception massage for string : SomeString

Руководствоваться нужно определением типа исключения. В зависимости от того, что вы хотите обрабатывать или видеть нужно и наследоваться от нужного класса.

13. Какой оператор позволяет принудительно выбросить исключение?

throw new Exception();

14. Есть ли дополнительные условия к методу, который потенциально может выбросить исключение?

Если это проверяемое исключение, то оно должно быть задекларировано в сигнатуре метода.

Public void someMethod() throws Exception { }

public void someMethod () throws Exception {

15. Может ли метод main выбросить исключение во вне и если да, то где будет происходить обработка данного исключения?

Может и оно будет передано в виртуальную машину Java (JVM).

16. Если оператор return содержится и в блоке catch и в finally, какой из них “главнее”?

Вернется из блока finally.

Public static void main(String args) { String what = method(); System.out.println(what); } public static String method() { try { return "SomeString"; } finally { return "Finally message"; } } //Вывод Finally message

public static void main (String args ) {

String what = method () ;

System . out . println (what ) ;

public static String method () {

try {

return "SomeString" ;

} finally {

return "Finally message" ;

//Вывод

Finally message

17. Что вы знаете о OutOfMemoryError?

OutOfMemoryError выбрасывается, когда виртуальная машина Java не может выделить (разместить) объект из-за нехватки памяти, а сборщик мусора не может высвободить ещё.

Область памяти, занимаемая java процессом, состоит из нескольких частей. Тип OutOfMemoryError зависит от того, в какой из них не хватило места.

1. java.lang.OutOfMemoryError: Java heap space
Не хватает места в куче, а именно, в области памяти в которую помещаются объекты, создаваемые программно в вашем приложении. Размер задается параметрами -Xms и -Xmx. Если вы пытаетесь создать объект, а места в куче не осталось, то получаете эту ошибку. Обычно проблема кроется в утечке памяти, коих бывает великое множество, и интернет просто пестрит статьями на эту тему.

2. java.lang.OutOfMemoryError: PermGen space
Данная ошибка возникает при нехватке места в Permanent области, размер которой задается параметрами -XX:PermSize и -XX:MaxPermSize.

3. java.lang.OutOfMemoryError: GC overhead limit exceeded
Данная ошибка может возникнуть как при переполнении первой, так и второй областей. Связана она с тем, что памяти осталось мало и GC постоянно работает, пытаясь высвободить немного места. Данную ошибку можно отключить с помощью параметра -XX:-UseGCOverheadLimit, но, конечно же, её надо не отключать, а либо решать проблему утечки памяти, либо выделять больше объема, либо менять настройки GC.

4. java.lang.OutOfMemoryError: unable to create new native thread

Выбрасывается, когда нет возможности создать еще потоки.

Подробнее в статье http://habrahabr.ru/post/117274/

18. Что вы знаете о SQLException? К какому типу checked или unchecked оно относится, почему?

SQLException предоставляет информацию об ошибках доступа к базе данных или других ошибках связанных с работой с базами данных.

SQLException относится к checked исключениям, а значит проверяется на этапе компиляции.

Споры об этом типе исключения идут о том, что разработчику приходится постоянно обрабатывать это исключение в коде, хотя большая часть ошибок возникает во время выполнения программы, т.е., по мнению многих, лучше бы отнести его к unchecked runtime исключениям.

try { // make some SQL call(s) } catch {SQLException e) { // log the exception return; // and give up }

try {

// make some SQL call(s)

} catch { SQLException e ) {

// log the exception

return ; // and give up

Аргумент Joshua Bloch из Effective Java Second Edition такой: сделав SQLException проверяемым — это попытка заставить разработчиков обработать исключение и обернуть его в новом уровне абстракции.

19. Что такое Error? В каком случае используется Error. Приведите пример Error’а.

Ошибки (Errors) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует пытаться обрабатывать в собственной программе, поскольку они связаны с проблемами уровня JVM. Например, исключения такого рода возникают, если закончилась память, доступная виртуальной машине.

За примером посмотрите картинку иерархии исключений вначале статьи. Как пример — OutOfMemoryError.

20. Какая конструкция используется в Java для обработки исключений?

Можно использовать try-catch-finally и c 7й Java try-with-resources. Первый способ:

try{ //здесь код, который потенциально может привести к ошибке } catch(SomeException e){ //в скобках указывается класс конкретной ожидаемой ошибки //здесь описываются действия, направленные на обработку исключений } finally{ //выполняется в любом случае (блок finally не обязателен) }

Try с ресурсами:

Старый способ BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { if (br != null) { br.close(); } } JDK 7 try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); }

Старыйспособ

BufferedReader br = new BufferedReader (new FileReader (path ) ) ;

try {

return br . readLine () ;

} finally {

if (br != null ) {

br . close () ;

JDK 7

try (BufferedReader br =

new BufferedReader (new FileReader (path ) ) ) {

return br . readLine () ;

Так же смотрите ответ к «Какие существуют способы обработки исключений?»

21. Предположим, есть блок try-finally. В блоке try возникло исключение и выполнение переместилось в блок finally. В блоке finally тоже возникло исключение. Какое из двух исключений “выпадет” из блока try-finally? Что случится со вторым исключением?

Ответ аналогичный случаю с двумя return — будет обработано в finally блоке. Если было выброшено два исключения — одно в try, второе в finally, то исключение в finally «проглотит» исключение выше (см. пример). Если до блока finally исключение было обработано, то мы можем получить информацию об исключении в блоке try и тем самым не потерять исключение, которое впоследствии может быть перезаписано в finally другим исключением.

public class TestExc { public static void main(String args) { Exception ex = twoExceptionsMethod(); System.out.println(ex.getClass()); String s = twoExceptionsMethod2(); System.out.println(s); } public static Exception twoExceptionsMethod() { try { return new IndexOutOfBoundsException(); } finally { return new NullPointerException(); } } public static String twoExceptionsMethod2() { try { throw new NullPointerException(); }catch (NullPointerException ex) { System.out.println(ex.getMessage()+ " catchBlock");; } finally { Exception ex2 = new Exception(); return ex2.getMessage() + "finallyBlock"; } } } //Вывод class java.lang.NullPointerException null catchBlock null finallyBlock

public class TestExc {

public static void main (String args ) {

Exception ex = twoExceptionsMethod () ;

System . out . println (ex . getClass () ) ;

Эта статья посвящается очень важному вопросу программирования - исключительным ситуациям и ошибкам (exceptions and errors).

В языке Java исключения (Exceptions) и ошибки (Errors) являются объектами. Когда метод вызывает, еще говорят "бросает" от слова "throws", исключительную ситуацию, он на самом деле работает с объектом. Но такое происходит не с любыми объектами, а только с теми, которые наследуются от Throwable.

Упрощенную диаграмму классов ошибок и исключительний вы можете увидеть на следующем рисунке:

RuntimeException, Error и их наследников еще называют unchecked exception , а всех остальных наследников класса Exception - checked exception .

Checked Exception обязывает пользователя обработать ее (использую конструкцию try-catch) или же отдать на откуп обрамляющим методам, в таком случае к декларации метода, который бросает проверяемое (checked) исключение, дописывают конструкцию throws , например:

Public Date parse(String source) throws ParseException { ... }

К unchecked исключениям относятся, например, NullPointerException, ArrayIndexOutOfBoundsException, ClassCastExcpetion и так далее. Это те ошибки, которые могут возникнут практически в любом методе. Несомненно, описывать каждый метод как тот, который бросает все эти исключения, было бы глупо.

1. Так когда же нужно бросать ошибки? . На этот вопрос можно ответить просто: если в методе возможна ситуация, которую метод не в состоянии обработать самостоятельно, он должен "бросать" ошибку. Но ни в коем случае нельзя использовать исключительные ситуации для управления ходом выполнения программы.

Чаще всего Exceptions бросаются при нарушении контракта метода. Контракт (contract) - это негласное соглашение между создателем метода (метод сделает и/или вернет именно то, что надо) и пользователем метода (на вход метода будут передаваться значения из множества допустимых).

Нарушение контракта со стороны создателя метода - это, например, что-нибудь на подобии MethodNotImplementedYetException:).

Пользователь метода может нарушить контракт, например, таким способом: на вход Integer.parseInt(String) подать строку с буквами и по заслугам получить NumberFormatException.

Часто при реализации веб-сервисов первыми строками методов я пишу конструкции вида:

Public Contract getContractById(String id) { if (id == null) throw new NullPointerException("id is null"); ... }

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

2. А что собственно бросать? . Выбор не то чтобы сильно велик, но и не однозначен: checked, unchecked (runtime), unchecked (error).

Сразу скажу, в подавляющем большинстве случаев Error вам не понадобится. Это в основном критические ошибки (например, StackOverflowError), с которыми пусть работает JVM.

Checked Exceptions, как было написано выше, заставляет программиста-пользователя написать код для ее обработки или же описать метод как "вызывающий исключительную ситуацию".

С unchecked exception можно поступить по-разному. В случае с такими ошибками, пользователь сам решает, будет он обрабатывать эту ошибку, или же нет (компилятор не заставляет это делать).

Можно написать следующее простое правило: если некоторый набор входящих в метод данных может привести к нарушению контракта, и вы считаете, что программисту-пользователю важно разобраться с этим (и что он сможет это сделать), описывайте метод с конструкцией throws, иначе бросайте unchecked exception.

3. Ну и как это обрабатывать? Обрабатывать ошибку лучше там, где она возникла. Если в данном фрагменте кода нет возможности принять решение, что делать с исключением, его нужно бросать дальше, пока не найдется нужный обработчик, либо поток выполнения программы не вылетит совсем.

Вы наверняка знаете, что обработка исключений происходит с помощью блока try-catch-finally. Сразу скажу вам такую вещь: никогда не используйте пустой catch блок! . Выглядит этот ужас так:

Try { ... } catch(Exception e) { }

Если Вы уверены, что исключения в блоке try не возникнет никогда, напишите комментарий, как например в этом фрагменте кода:

StringReader reader = new StringReader("qwerty"); try { reader.read(); } catch (IOException e) { /* cannot happen */ }

Если же исключение в принципе может возникнуть, но только действительно в "исключительной ситуации" когда с ним ничего уже сделать будет нельзя, лучше оберните его в RuntimeException и пробросьте наверх, например:

String siteUrl = ...; ... URL url; try { url = new URL(siteUrl); } catch (MalformedURLException e) { throw new RuntimeException(e); }

Скорее всего ошибка здесь может возникнуть только при неправильной конфигурации приложения, например, siteUrl читается из конфигурационного файла и кто-то допустил опечатку при указании адреса сайта. Без исправления конфига и перезапуска приложения тут ничего поделать нельзя, так что RuntimeException вполне оправдан.

4. Зачем нужно все это делать? А почему бы и нет:). Если серьезно - правильное использование Exceptions и корректная их обработка сделают код более понятным, гибким, структурированным и возможным для повторного использования.

Updated 28.08.2009: Хочу показать вам несколько интересных моментов, которые касаются исключений и блоков try-catch-finally.

Можно ли сделать так, чтобы блок finally не выполнился? Можно:

Public class Test1 { public static void main(String args) { try { throw new RuntimeException(); } catch (Exception e) { System.exit(0); } finally { System.out.println("Please, let me print this."); } } }

Ну и еще одна интересная вещь. Какое исключение будет выброшено из метода:

Public class Test { public static void main(String args) { try { throw new NullPointerException(); } catch (NullPointerException e) { throw e; } finally { throw new IllegalStateException(); } } }

Правильный ответ - IllegalStateException. Не смотря на то, что в блоке catch происходит повторный "выброс" NPE, после него выполняется блок finally, который перехватывает ход выполнения программы и бросает исключение IllegalStateException.

Жду ваших вопросов и комментариев.



Комментариев: 2

Но ни в коем случае нельзя использовать исключительные ситуации для реализации частей бизнесс-логики.

Я бы сказал не стоит использовать исключения для управления flow алгоритма (типа выхода из вложенного цикла и все такое). А вот для реализации частей бизнес-логики как раз таки иногда и нужно, но только те которые checked. Классический пример - снятие денег со счета, когда выкидывается исключение, говорящее о том что денюшок то не хватает. Вот тут как раз клиенту метода снятия надо реализовать бизнес-логику по обработке такой ситуации.

Ну а в тех случаях когда речь идет о нарушении контракта метода (не бизнес-ограничений) не надо и задумываться - только unchecked, и ловить их должен код, находящийся в самом начале потока, и ничего кроме логирования информации об ошибки с ними сделать он не может, да и не должен.

P.S. Ну конечно бывают ситуации исключительные. Но это не более 20%.

lucker wrote: Ну а в тех случаях когда речь идет о нарушении контракта метода (не бизнес-ограничений) не надо и задумываться - только unchecked, и ловить их должен код, находящийся в самом начале потока, и ничего кроме логирования информации об ошибки с ними сделать он не может, да и не должен.

такой подход приведет к тому что код в начале потока будет в 80% случаев получать исключение неизвестно по какой причине и как возникшее, например стэк трэйс на вэб странице, ни один из модулей который будет использовать такой метод и понятия не будет иметь о том что гдето в глубине ктото выбросил анчекед исключение и результат его может быть самым удручающим, например: если такой метод кто-то начнет использовать в цикле то из-за одноко неправильного объекта переданого в метод, который выкинет анчекед из-за нарушения контракта, вместо скажем ожидаемого списка из нескольких строк на экране клиент не увидит ни одного, а мог бы просто увидеть на один меньше (тот который послужил причиной исключения) А произойдет это потому что девелопер который будет писать вывод понятия не будет иметь что данный конкретный метод может просто выкинуть тот или иной рантайм, если такой метод в случае нарушения контракта выбросит чекед исключение то пользователь метода будет иметь информацию и решит что ему делать с данным исключением, код будет иметь более предсказуемое поведение а следственно станет более професиональным.

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

Статья кстати выглядит немного поверхностной, основная проблема в написании комерческого софта именно в том чтобы сделать его реюзабельным и легко изменяемым к постоянно меняющимся требованиям при этом надежным, предсказуемым и устойчивым. Поэтому приведенная цитата о том что 90% кода обрабатывает исключения а 10% делает работу - это цитата человека который врядли писал что-то что потом используют другие… поскольку работа програмы включает в себя и надежность и предсказуемость и повторяемость результатов и масштабируемость и возможность использовать код еще кем-то, все то что отличает комерческий код профи от кода студента.

Исключениями или исключительными ситуациями (состояниями) называются ошибки, возникшие в программе во время её работы.

Все исключения в Java являются объектами. Поэтому они могут порождаться не только автоматически при возникновении исключительной ситуации, но и создаваться самим разработчиком.

Иерархия классов исключений:

Исключения делятся на несколько классов, но все они имеют общего предка — класс Throwable. Его потомками являются подклассы Exception и Error.

Исключения (Exceptions) являются результатом проблем в программе, которые в принципе решаемы и предсказуемы. Например, произошло деление на ноль в целых числах.

Ошибки (Errors) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует пытаться обрабатывать в собственной программе, поскольку они связаны с проблемами уровня JVM. Например, исключения такого рода возникают, если закончилась память, доступная виртуальной машине. Программа дополнительную память всё равно не сможет обеспечить для JVM.

В Java все исключения делятся на три типа: контролируемые исключения (checked) и неконтролируемые исключения (unchecked), к которым относятся ошибки (Errors) и исключения времени выполнения (RuntimeExceptions, потомок класса Exception).

Контролируемые исключения представляют собой ошибки, которые можно и нужно обрабатывать в программе, к этому типу относятся все потомки класса Exception (но не RuntimeException).

Обработка исключения может быть произведена с помощью операторов try…catch, либо передана внешней части программы. Например, метод может передавать возникшие в нём исключения выше по иерархии вызовов, сам его не обрабатывая.

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

Откомпилируем и запустим такую программу:

Class Main { public static void main(String args) { int a = 4; System.out.println(a/0); } }

В момент запуска на консоль будет выведено следующее сообщение:

Exception in thread "main" java.lang.ArithmeticException: / by zero at Main.main(Main.java:4)

Из сообщения виден класс случившегося исключения — ArithmeticException. Это исключение можно обработать:

Class Main { public static void main(String args) { int a = 4; try { System.out.println(a/0); } catch (ArithmeticException e) { System.out.println("Произошла недопустимая арифметическая операция"); } } }

Теперь вместо стандартного сообщения об ошибке будет выполняться блок catch, параметром которого является объект e соответствующего исключению класса (самому объекту можно давать любое имя, оно потребуется в том случае, если мы пожелаем снова принудительно выбросить это исключение, например, для того, чтобы оно было проверено каким-то ещё обработчиком).

В блок try при этом помещается тот фрагмент программы, где потенциально может возникнуть исключение.

Одному try может соответствовать сразу несколько блоков catch с разными классами исключений.

Import java.util.Scanner; class Main { public static void main(String args) { int m = {-1,0,1}; Scanner sc = new Scanner(System.in); try { int a = sc.nextInt(); m[a] = 4/a; System.out.println(m[a]); } catch (ArithmeticException e) { System.out.println("Произошла недопустимая арифметическая операция"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Обращение по недопустимому индексу массива"); } } }

Если запустив представленную программу, пользователь введётся с клавиатуры 1 или 2, то программа отработает без создания каких-либо исключений.

Если пользователь введёт 0, то возникнет исключение класса ArithmeticException, и оно будет обработано первым блоком catch.

Если пользователь введёт 3, то возникнет исключение класса ArrayIndexOutOfBoundsException (выход за приделы массива), и оно будет обработано вторым блоком catch.

Если пользователь введёт нецелое число, например, 3.14, то возникнет исключение класса InputMismatchException (несоответствие типа вводимого значение), и оно будет выброшено в формате стандартной ошибки, поскольку его мы никак не обрабатывали.

Можно, однако, добавить обработчик для класса Exception, поскольку этот класс родительский для всех остальных контролируемых исключений, то он будет перехватывать любые из них (в том числе, и InputMismatchException).

Import java.util.Scanner; class Main { public static void main(String args) { int m = {-1,0,1}; int a = 1; Scanner sc = new Scanner(System.in); try { a = sc.nextInt(); m = 4/a; System.out.println(m[a]); } catch (ArithmeticException e) { System.out.println("Произошла недопустимая арифметическая операция"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Обращение по недопустимому индексу массива"); } catch (Exception e) { System.out.println("Произошло ещё какое-то исключение"); } } }

Поскольку исключения построены на иерархии классов и подклассов, то сначала надо пытаться обработать более частные исключения и лишь затем более общие. То есть поставив первым (а не третьим) блок с обработкой исключения класса Exception, мы бы никогда не увидели никаких сообщений об ошибке, кроме «Произошло ещё какое-то исключение» (все исключения перехватились бы сразу этим блоком и не доходили бы до остальных).

Необязательным добавлением к блокам try…catch может быть блок finally. Помещенные в него команды будут выполняться в любом случае, вне зависимости от того, произошло ли исключение или нет. При том, что при возникновении необработанного исключения оставшаяся после генерации этого исключения часть программы — не выполняется. Например, если исключение возникло в процессе каких-то длительных вычислений, в блоке finally можно показать или сохранить промежуточные результаты.

2010, Алексей Николаевич Костин. Кафедра ТИДМ математического факультета МПГУ.

В данной статье рассматривается используемый в Java механизм обработки исключений. Исключение в Java - это объект, который описывает исключительное состояние, возникшее в каком-либо участке программного кода. Когда возникает исключительное состояние, создается объект класса Exception . Этот объект пересылается в метод, обрабатывающий данный тип исключительной ситуации. Исключения могут возбуждаться и для того, чтобы сообщить о некоторых нештатных ситуациях.

Ключевые слова исключений try, catch, throw, throws, finally

Механизм исключительных ситуаций в Java поддерживается пятью ключевыми словами:

  • catch,
  • throw,
  • throws,
  • finally.

Ниже приведена общая форма блока обработки исключений.

Try { // блок кода } catch ( е) { // обработчик исключений типа ExceptionType1 } catch ( е) { // обработчик исключений типа ExceptionType2 } finally { // ... }

Типы исключений

В вершине иерархии исключений стоит класс Throwable , который наследуется от Object . Каждый из типов исключений является подклассом Throwable. Два непосредственных наследника класса Throwable делят иерархию подклассов исключений на две различные ветви. Иерархия классов представлена на рисунке.

Класс Ехception используется для описания исключительных ситуации, которые должны перехватываться программным кодом пользователя. Класс Error предназначен для описания исключительных ситуаций, которые при обычных условиях не должны перехватываться в пользовательской программе.

Неперехваченные исключения

Объекты-исключения автоматически создаются исполняющей средой Java в результате возникновения определенных исключительных ситуаций. Пример программы, в которой создаем исключительную ситуацию при делении на нуль.

Package samples; class TestException { public static void main(String args) { int d = 0; int a = 42 / d; System.out.println ("a = " + a); } }

В консоль будет выведено следующее сообщение.

Exception in thread "main" java.lang.ArithmeticException: / by zero at samples.TestException.main(TestException.java:8)

Следует обратить внимание на тот факт, что типом возбужденного исключения был не Exception и не Throwable . Это подкласс класса Exception , а именно: ArithmeticException , поясняющий, какая ошибка возникла при выполнении программы.

Изменим класс добавлением статического метода subroutine , в котором создадим такую же исключительную ситуацию.

Package samples; public class TestException { static void subroutine() { int d = 0; int a = 10 / d; System.out.println ("a = " + a); } public static void main(String args) { TestException.subroutine(); } }

Сообщение выполнения программы показывает, как обработчик исключений исполняющей системы Java выводит содержимое всего стека вызовов.

Exception in thread "main" java.lang.ArithmeticException: / by zero at samples.TestException.subroutine(TestException.java:8) at samples.TestException.main(TestException.java:14)

Перехват исключений try/catch

Для защиты программного кода от исключений необходимо использовать связанные блоки с ключевыми словами try catch ; catch помещается сразу же после try-блока. В блоке catch задается тип исключения, которое необходимо обработать.

Class TestException { public static void main(String args) { try { int d = 0; int a = 42 / d; } catch (ArithmeticException e) { System.out.println("division by zero"); } } }

Целью большинства хорошо сконструированных catch -разделов должна быть обработка возникшей исключительной ситуации и приведение переменных программы в некоторое разумное состояние - такое, чтобы программу можно было продолжить так, будто никакой ошибки и не было (в нашем примере выводится предупреждение - division by zero).

Несколько разделов catch

В отдельных случаях блок программного кода может вызвать исключения различных типов. Для того, чтобы локализовать обработку подобных ситуаций, можно использовать несколько catch -разделов для одного try-блока . Блоки наиболее специализированных классов исключений должны идти первыми, поскольку ни один подкласс не будет достигнут, если поставить его после суперкласса.

В следующем примере перехватывается два различных типа исключений, причем за этими двумя специализированными обработчиками следует раздел catch общего назначения, перехватывающий все подклассы класса Throwable .

Class MultiCatch { static int c = { 1 }; public static void main(String args) { try { int a = args.length; System.out.println("a = " + String.valueOf(a)); int b = 23 / a; c = 33; } catch (ArithmeticException e) { System.out.println("ArithmeticException: " + e.getMessage()); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("ArrayIndexOutOfBoundsException: " + e.getMessage()); } } }

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

А = 0 div by 0: java.lang.ArithmeticException: / by zero a = 1 array index oob: java.lang.ArrayIndexOutOfBoundsException:33

Вложенные операторы try

Операторы try можно вкладывать друг в друга. Если у оператора try низкого уровня нет раздела catch , соответствующего возбужденному исключению, стек будет развернут на одну ступень выше, и в поисках подходящего обработчика будут проверены разделы catch внешнего оператора try. Пример вложения двух операторов try catch друг в друга посредством вызова метода.

Class MultiNest { static int c = { 1 }; static void checkArray() { try { c = 33; } catch(ArrayIndexOutOfBoundsException e) { System.out.println "ArrayIndexOutOfBoundsException: " + e.getMessage()); } } public static void main(String args) { try { int a = args.length(); System.out.println("a = " + a); int b = 23 / a; checkArray(); } catch (ArithmeticException e) { System.out.println("ArithmeticException: " + e.getMessage()); } } }

Возбуждение исключений throw

Программа может явно вызывать исключение, используя оператор throw . После выполнения оператора throw процесс выполнения программы приостанавливается и последующие операторы не выполняются. JVM просматривает ближайший блоки try ... catch , соответствующий типу исключения, для "передачи управления". Если подходящий блок не будет найден, то обработчик исключений остановит программу и "распечатает" при этом состояние стека вызовов.

Пример исключения, в котором сначала создается объект-исключение, затем оператор throw возбуждает исключительную ситуацию, после чего то же исключение возбуждается повторно - на этот раз уже кодом перехватившего его в первый раз раздела catch .

Class TestThrow { static void method() { try { throw new NullPointerException("Exception in method"); } catch (NullPointerException e) { System.out.println(e.getMessage()); throw e; } } public static void main(String args) { try { method(); } catch(NullPointerException e) { System.out.println("Catch inside main: " + e.getMessage()); } } }

Результат выполнения программы приведен ниже.

Exception in method Catch inside main: Exception in method

Объявление об исключении throws

Если метод может возбуждать исключения, которые сам не обрабатывает, то он должен объявить об этом, чтобы вызывающие его другие методы могли защитить себя от этих исключений. Для задания списка исключений, которые могут возбуждаться методом, используется ключевое слово throws .

Если метод в явном виде (т.е. с помощью оператора throw ) возбуждает исключение, тип класса исключений должен быть указан в операторе throws в объявлении этого метода. Принимая данное положение во внимание синтаксис определения метода должен быть описан следующим образом:

Public class TestThrow { static void method() throws IllegalAccessException { try { System.out.println("inside method"); throw new IllegalAccessException ("Exception in method"); } catch (NullPointerException e) { System.out.println(e.getMessage()); } } public static void main(String args) { try { method(); } catch(IllegalAccessException e) { System.out.println("Catch inside main: " + e.getMessage()); } } }

Результат работы примера:

Inside method Catch inside main: Exception in method

Ключевое слово finally

В случае, когда необходимо гарантировано выполнить определенный участок кода необходимо использовать ключевое слово finally . Использование связи try...finally позволяет обеспечить выполнение кода независимо от того, какие исключения были возбуждены и перехвачены, даже в тех случаях, когда в методе нет соответствующего возбужденному исключению раздела catch.

У каждого раздела try должен быть по крайней мере или один раздел catch или блок finally . Блок finally очень удобен для закрытия файлов и освобождения любых других ресурсов, захваченных для временного использования в начале выполнения метода.

Ниже приведен пример класса с двумя методами, завершение которых происходит по разным причинам, но в обоих перед выходом выполняется код раздела finally .

Public class TestFinally { static void methodA() { try { System.out.println("inside methodA"); throw new RuntimeException("Exception in methodA"); } finally { System.out.println("finally inside methodA"); } } static void methodB() { try { System.out.println("inside methodB"); return; } finally { System.out.println("finally inside methodB"); } } public static void main(String args) { try { methodA(); } catch (Exception e) { System.out.println("Catch exception iinside main"); } methodB(); } }

В тестовом примере в методе methodA возбуждается исключение. Но перед преждевременным выходом из блока try , выполняется раздел finally . Во втором методе methodB завершается работа в try -блоке оператором return , но и при этом перед выходом из метода выполняется программный код блока finally . Результат работы тестового примера:

Inside methodA finally inside methodA Catch exception iinside main inside methodB finally inside methodB

Обработка исключений в Java предоставляет исключительно мощный механизм для управления сложными программами. Ключевые слова try, throw, catch позволяют выполнять обработку ошибок и разных нештатных ситуаций в программе.

Наследование исключений

catch - полиморфная конструкция, т.е. catch по типу parent перехватывает исключения любого типа, которые является Parent"ом.

Public class TestException { public static void main(String args) { try { System.err.print("level 0"); throw new RuntimeException(); System.err.print("level 1"); } catch (Exception e) { // catch Exception ПЕРЕХВАТ RuntimeException System.err.print("level 2"); } System.err.println("level 3"); } }

В результате в консоли увидим

Level 0 level 2 level 3

Error и Exception из параллельных веток наследования от Throwable , поэтому catch по одному «брату» не может поймать другого «брата».

Public class TestError { public static void main(String args) { try { System.err.println("level 0"); if (true) { throw new Error(); } System.err.println("level 1"); } catch (Exception e) { System.err.println("level 2"); } System.err.println("level 3"); } }

Результат выполения программы

Level 0 Exception in thread "main" java.lang.Error at TestError.main(TestFinally.java:8)

Множественные исключения

Объявление исключений в методе может быть множественным. Пример:

Import java.io.EOFException; import java.io.FileNotFoundException; public class MultiException { // объявляем исключения public static void main(String args) throws EOFException, FileNotFoundException { if (System.currentTimeMillis() % 2 == 0) { throw new EOFException(); } else { throw new FileNotFoundException(); } } }

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

Когда может понадобиться обработка исключений

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

Обработка исключений Java

Что необходимо учитывать? Язык Java обладает своим встроенным функционалом обработки исключений. Конечно же большой процент ошибок отлавливается ещё на стадии компиляции, когда система автоматически сообщит о том, что использовать её дальше невозможно. Но существует и такой вид исключений, который возникает во время работы программы. Разработчик должен суметь предвидеть это и спроектировать код таким образом, чтобы он не вызвал ошибки, а обработал её особым способом или передал управление в другую ветку.

В Java такой отлов исключений навязывается компилятором, поэтому типичные проблемы известны и имеют свою стандартную схему исполнения.

Типичные исключения

Самым простым примером, при котором можно получить исключение — это деление. Несмотря на всю его простоту, в выражении, в качестве делителя, может оказаться ноль, что приведёт к ошибке. Хорошо, если его появление можно предсказать ранее и предотвратить. Но такой вариант доступен не всегда, поэтому отлов исключения нужно организовать непосредственно при возникновении «деления на ноль».

В Java механизм обработки перехвата ошибки выглядит так:

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

Простейший пример создания ошибки может выглядеть таким образом:

throw new NullPointerException();

Здесь переменная a проверяется на инициализацию, т.е. не равна ли ссылка на объект null. В случае, если такая ситуация возникла и нужна особая обработка, выбрасывается исключение с помощью throw new NullPointerException().

Немного подробностей о ключевых словах

При работе с исключениями часто приходится использовать ключевые слова Java для обозначения того или иного действия. В данном языке программирования их пять:

  • Try. уже встречалось и означает оно переход в участок кода, который может сгенерировать исключение. Блок ограничивается фигурными скобками {}.
  • Catch. Перехватывает нужный тип исключения и обрабатывает его соответствующим образом.
  • Finally. Данное ключевое слово является дополнительным и служит для выполнения некоего участка кода, который необходим в любом случае, даже если ни одно исключение не перехвачено. Добавляется непосредственно после блока try.
  • Throw — позволяет создавать исключения Java в любом месте кода.
  • Throws — ключевое слово, которое ставится в сигнатуре метода. Оно означает, что последующий код может выбросить исключение Java указанного типа. Такая метка служит сигналом для разработчиков, что нужно иметь в виду — метод может сработать не так, как от него ожидают.

Отлов с помощью try

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

В Java код заворачивается в специальный блок try, внутри которого может быть сгенерировано исключение. Таким образом, в него помещается сразу несколько непредвиденных ситуаций, которые будут отловлены в одном месте, не расползаясь по коду.

Самый типичный код с блоком обработки выглядит так:

//Здесь будет определён код, который может породить исключение

} catch (Тип_исключения_1 идентификатор_1) {

} catch (Тип_исключения_2 идентификатор_2) {

//Здесь происходит обработка исключения, согласно его типу и условиям;

Ключевое слово catch сообщает о том, что код, подвергнутый проверке на исключение, нужно обработать так, как описано далее, при условии, что он соответствует его типу. Идентификатор может использоваться внутри блока кода обработки как аргументы.

Finally

Как стало понятно из предыдущей главы, блоки catch ловят исключения и обрабатывают их. Но очень часто возникает ситуация, когда должен выполниться некий код вне зависимости от того, были ли отловлены ошибки. Для этого существует ключевое слово finally. Оно применяется для увеличения значений различных счётчиков, закрытия файлов или соединений с сетью.

В данном участке представлены несколько блоков catch с придуманными методами отлова исключений. К примеру, код, содержащийся в try порождает непредвиденную ситуацию типа Cold. Тогда в консоль будут выведены выражения «Caught cold!» и «Is that something to cheer about?». То есть блок finally выполняется в любом случае.

На самом деле способ избежать запуска finally существует. Связан он с завершением работы виртуальной машины. Найти, как это реализовать, можно на просторах сети Интернет.

Ключевое слово throw

Throw генерирует исключение. Его синтаксис выглядит так:

throw new NewException();

Здесь создаётся новое исключение с типом NewException(). В качестве типа могут использоваться уже входящие в стандартные библиотеки Java классы и определённые ранее разработчиком собственного производства.

Такая конструкция входит в описание какого-либо метода, вызов которого затем должен происходить в рамках блока try, для того, чтобы была возможность его перехватить.

Ключевое слово throws

Что делать, если в процессе разработки возникла ситуация, когда метод может сгенерировать исключение, но не в состоянии правильно обработать. Для этого в сигнатуре метода указывается слово throws и тип возможного исключения.

Эта метка является своеобразным указателем для клиентских разработчиков о том, что метод не способен обработать своё же исключение. К тому же, если тип ошибки является проверяемым, то компилятор заставит явно это указать.

Try с ресурсами

В Java версии 7 разработчики включили такое важное нововведение, как обработка блока try с ресурсами.

Многие создаваемые объекты в Java, после их использования должны быть закрыты для экономии ресурсов. Раньше приходилось это учитывать и останавливать такие экземпляры вручную. Теперь же в них появился интерфейс AutoClosable. Он помогает автоматически закрывать уже использованные объекты, помещённые в блок try. Благодаря такому подходу писать код стало удобней, в его читаемость значительно повысилась.

Собственные классы исключений Java

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

Простейший способ создания — унаследовать от наиболее подходящего к контексту объекта.

Здесь произошло наследование от Exception, класса, который используется для определения собственных исключений. В MyException имеются два конструктора — один по умолчанию, второй — с аргументом msg типа String.

Затем в public классе FullConstructors реализован метод f, сигнатура которого содержит throws MyException. Это ключевое слово означает, что f может выбросить исключение Java типа MyException. Далее в теле метода производится вывод текстовой информации в консоль и собственно сама генерация MyException, посредством throw.

Второй метод немного отличается от первого тем, что при создании исключения, ему передается строковый параметр, который будет отражён в консоли при отлове. В main видно, что f() и g() помещены в блок проверки try, а ключевое слово catch настроено на отлов MyException. Результатом обработки будет вывод сообщения об ошибке в консоль:

Таким образом получилось добавить исключения Java, созданные собственноручно.

Архитектура исключений

Как и все объекты в Java, исключения также наследуются и имеют иерархическую структуру. Корневым элементом всех ошибок, выбрасываемых в этом языке программирования является класс java.lang.Throwable. От него наследуются два вида — Error и Exception.

Error — оповещает о критических ошибках и представляет собой непроверяемые исключения Java. Перехват и обработка таких данных в большинстве случаев происходит на стадии разработки и не нуждается во внедрении в код конечного приложения.

Наиболее часто используемым классом для создания и анализа исключений служит Exception. Который, в свою очередь, делится на несколько веток, в том числе RuntimeException. К RuntimeException относятся исключения времени выполнения, то есть происходящие во время работы программы. Все унаследованные от него классы являются непроверяемыми.

Часто встречаемые исключения

В Java исключения, список которых представлен ниже, используются наиболее часто, поэтому стоит описать каждый из них подробней:

  • ArithmeticException. Сюда входят ошибки связанные с арифметическими операциями. Самый яркий пример — деление на ноль.
  • ArrayIndexOutOfBoundsException — обращение к номеру элемента массива, который превышает общую его длину.
  • ArrayStoreException — попытка присвоить элементу массива несовместимого типа.
  • ClassCastException — попытка неправильного приведения одного типа к другому.
  • IllegalArgumentException — использование неправильного аргумента в вызове метода.
  • NegativeArraySizeException — исключение при создании массива отрицательного размера.
  • NullPointerException — неправильное использование ссылки на null.
  • NumberFormatException — возникает при неверном преобразовании строки в число.
  • UnsupportedOperationException — операция не поддерживается.

Данные примеры представляют собой непроверяемые типы исключений Java. А вот так выглядят проверяемые:

  • ClassNotFoundException — класс не обнаружен.
  • IllegalAcccessException — ограничение доступа к классу.
  • InterruptedException — прерывание работы потока.
  • NoSuchFieldException — не существует требуемое поле.

Интерпретация исключений

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

NullPointerException. Самым первым случаем, когда возникает исключение, является обращение к ссылке на объект, которая равна null. Также это распространяется на методы нулевого экземпляра класса. NullPointerException может быть брошен и в случае получения длины массива равной null. Избежать таких ситуаций поможет периодическая проверка объектов на null.

ArrayIndexOutOfBoundsException. Любая программа не может существовать без использования массивов. Соответственно, частое обращение к ним может порождать и ошибки. Возникает исключение, когда разработчик пытается обратиться к элементу массива, который отсутствует в списке индексов. Например, запрашиваемое значение выше длины или меньше нуля. Очень часто появляется в результате того, что счёт в массиве начинается с нуля.

Выводы

Обработка исключений Java — мощный инструмент среды, который значительно облегчает работу программиста и позволяет ему создавать чистый и лишенный ошибок код. От того, насколько плавно и стабильно функционирует приложение, зависит статус и репутация компании-разработчика.

Конечно, в более или менее простых программах отследить внештатные ситуации гораздо проще. А вот в больших автоматизированных комплексах на несколько сотен тысяч строк такое возможно только в результате проведения длительной отладки и тестирования.

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



© 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows