multi-catch
В жизни так бывает, что catch-блоки по разным исключительным ситуациям выглядят идентично:
Можем, конечно, во избежании дубликации пользоваться полиморфностью перехвата и "ловить предка" (однако в такой catch-блок можем наловить и лишнего - любого наследника предка, в нашем примере, скажем NullPointerException):
more precise rethrow
Однако, вот я хочу сохранить переменную e, какой тип выбрать? Так не выйдет:
В жизни так бывает, что catch-блоки по разным исключительным ситуациям выглядят идентично:
import java.io.IOException;
public class ExampleMultiCatch0 {
public static void main(String[] args) {
try {
if (args == null) {
throw new IOException();
} else {
throw new InterruptedException();
}
} catch (IOException e) {
System.out.println("O mama ...");
} catch (InterruptedException e) {
System.out.println("O mama ...");
}
}
}
Если содержимое блоков многострочно, то создаем специальный метод и не забываем его вызывать в каждом catch-блоке:
import java.io.IOException;
public class ExampleMultiCatch00 {
public static void main(String[] args) {
try {
if (args == null) {
throw new IOException();
} else {
throw new InterruptedException();
}
} catch (IOException e) {
repair();
} catch (InterruptedException e) {
repair();
}
}
private static void repair() {
System.out.println("O mama ...");
System.out.println("O daddy ...");
System.out.println("O baby ...");
}
}
Можем, конечно, во избежании дубликации пользоваться полиморфностью перехвата и "ловить предка" (однако в такой catch-блок можем наловить и лишнего - любого наследника предка, в нашем примере, скажем NullPointerException):
import java.io.IOException;
public class ExampleMultiCatch000 {
public static void main(String[] args) {
try {
if (args == null) {
throw new IOException();
} else {
throw new InterruptedException();
}
} catch (Exception e) {
System.out.println("O mama ...");
}
}
}
Однако, хорошо бы синтаксически подчеркнуть тот факт, что реакция на два разных исключения идентична. Для этого в Java 7 ввели multi-catch блок:
import java.io.IOException;
public class ExampleMultiCatch1 {
public static void main(String[] args) {
try {
if (args == null) {
throw new IOException();
} else {
throw new InterruptedException();
}
} catch (IOException | InterruptedException e) {
System.out.println("O mama ...");
}
}
}
Используется синтаксис сходный с логическим ИЛИ:
public class ExampleMultiCatch11 {
public static void main(String[] args) {
if (3 < args.length | args.length < 33) {
System.out.println("!");
}
}
}
more precise rethrow
Однако, вот я хочу сохранить переменную e, какой тип выбрать? Так не выйдет:
import java.io.IOException;
public class ExampleMultiCatch2 {
public static void main(String[] args) {
try {
if (args == null) {
throw new IOException();
} else {
throw new InterruptedException();
}
} catch (IOException | InterruptedException e) {
IOException | InterruptedException x = e; // don't compile
}
}
}
Отступление: хотя такое вот пропускает:
x
Ну хорошо, возьмем общего предка:
import java.io.IOException;
public class ExampleMultiCatch22 {
public static void main(String[] args) {
try {
if (args == null) {
throw new IOException();
} else {
throw new InterruptedException();
}
} catch (IOException | InterruptedException e) {
Exception x = e;
}
}
}
Однако вот такое компилятор не пропускает:
import java.io.IOException;
public class ExampleMultiCatch222 {
public static void main(String[] args) throws IOException, InterruptedException {
try {
if (args == null) {
throw new IOException();
} else {
throw new InterruptedException();
}
} catch (IOException | InterruptedException e) {
Exception x = e;
System.out.println("O mama ...");
throw x; // don't compile
}
}
}
А так неохота (мы же точно знаем, что повторно кидаем одно-из-двух, а не более общего предка):
import java.io.IOException;
public class ExampleMultiCatch2222 {
public static void main(String[] args) throws Exception {
try {
if (args == null) {
throw new IOException();
} else {
throw new InterruptedException();
}
} catch (IOException | InterruptedException e) {
Exception x = e;
System.out.println("O mama ...");
throw x;
}
}
}
Однако, если не сохранять e в переменную (которой надо объявить тип, то все хорошо):
public class ExampleMultiCatch22222 {
public static void main(String[] args) throws IOException, InterruptedException {
try {
if (args == null) {
throw new IOException();
} else {
throw new InterruptedException();
}
} catch (IOException | InterruptedException e) {
System.out.println("O mama ...");
throw e;
}
}
}
Начиная с Java 7 этот трюк работает также в такой форме:
import java.io.IOException;
public class ExampleMultiCatch3 {
public static void main(String[] args) throws IOException, InterruptedException {
try {
if (args == null) {
throw new IOException();
} else {
throw new InterruptedException();
}
} catch (Exception e) {
System.out.println("O mama ...");
throw e;
}
}
}