В този урок ще се научим да се справяме с множество изключения в Java с помощта на примери.
Преди Java 7 трябваше да напишем множество кодове за обработка на изключения за различни видове изключения, дори ако имаше излишък на код.
Да вземем пример.
Пример 1: Множество блокове за улов
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (ArithmeticException e) ( System.out.println(e.getMessage()); ) catch (ArrayIndexOutOfBoundsException e) ( System.out.println(e.getMessage()); ) ) )
Изход
/ по нула
В този пример могат да възникнат две изключения:
ArithmeticException
защото се опитваме да разделим число на 0.ArrayIndexOutOfBoundsException
защото декларирахме нов целочислен масив с граници от 0 до 9 и се опитваме да присвоим стойност на индекс 10.
Разпечатваме съобщението за изключение и в двата catch
блока, т.е. дублиран код.
Асоциативността на оператора за присвояване =
е отдясно наляво, така че ArithmeticException
се хвърля първо със съобщението / от нула.
Обработвайте множество изключения в блок за улов
В Java SE 7 и по-нови версии вече можем да хванем повече от един тип изключения в един catch
блок.
Всеки тип изключение, който може да се обработва от catch
блока, се отделя с помощта на вертикална лента или тръба |
.
Синтаксисът му е:
try ( // code ) catch (ExceptionType1 | Exceptiontype2 ex) ( // catch block )
Пример 2: Блок с много улов
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (ArithmeticException | ArrayIndexOutOfBoundsException e) ( System.out.println(e.getMessage()); ) ) )
Изход
/ по нула
Улавянето на множество изключения в един catch
блок намалява дублирането на кода и увеличава ефективността.
Байтовият код, генериран по време на компилирането на тази програма, ще бъде по-малък от програмата с множество catch
блокове, тъй като няма излишък на код.
Забележка: Ако даден catch
блок обработва множество изключения, параметърът catch е имплицитно final
. Това означава, че не можем да присвояваме никакви стойности за улавяне на параметри.
Улов на база Изключение
При улавяне на множество изключения в един catch
блок, правилото се обобщава на специализирано.
Това означава, че ако в catch
блока има йерархия от изключения , можем да хванем само основното изключение, вместо да хващаме множество специализирани изключения.
Да вземем пример.
Пример 3: Улавяне само на основен клас на изключение
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (Exception e) ( System.out.println(e.getMessage()); ) ) )
Изход
/ по нула
Знаем, че всички класове изключения са подкласове на Exception
класа. Така че, вместо да хващаме множество специализирани изключения, можем просто да хванем Exception
класа.
Ако основният клас на изключение вече е посочен в catch
блока, не използвайте дъщерни класове на изключения в същия catch
блок. В противен случай ще получим грешка при компилация.
Да вземем пример.
Пример 4: Улавяне на базови и дъщерни класове на изключения
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (Exception | ArithmeticException | ArrayIndexOutOfBoundsException e) ( System.out.println(e.getMessage()); ) ) )
Изход
Main.java:6: грешка: Алтернативите в оператор за многократно хващане не могат да бъдат свързани чрез подкласиране
В този пример ArithmeticException
и ArrayIndexOutOfBoundsException
са двата подкласа на Exception
класа. И така, получаваме грешка при компилацията.