Обработка исключений в лямбда-выражении java 8
Введение
лямбда-выражения были введены в java 8, лямбда-выражения могут сделать наш код более кратким, а бизнес-логику более понятной, но функциональный интерфейс, используемый в лямбда-выражениях, не очень хорошо обрабатывает исключения, потому что эти функциональные интерфейсы, предоставляемые JDK, обычно не выбрасываются исключения, что означает, что нам нужно обрабатывать исключение вручную.
Поскольку исключения делятся на непроверенное исключение и проверенное исключение, мы обсуждаем их отдельно.
Обработка непроверенных исключений
Непроверенное исключение также называется RuntimeException, а RuntimeException обычно возникает из-за проблемы с нашим кодом. RuntimeException не нужно перехватывать. То есть, если есть исключение RuntimeException, его можно скомпилировать, не перехватывая.
Давайте посмотрим на пример:
List<Integer> integers = Arrays.asList(1,2,3,4,5);
integers.forEach(i -> System.out.println(1 / i));
Этот пример может быть успешно скомпилирован, но есть проблема выше, если в списке есть 0, будет выброшено исключение ArithmeticException.
Хотя это непроверенное исключение, мы все равно хотим его обработать:
integers.forEach(i -> {
try {
System.out.println(1 / i);
} catch (ArithmeticException e) {
System.err.println(
"Arithmetic Exception occured : " + e.getMessage());
}
});
В приведенном выше примере мы использовали try и catch для обработки исключений, что просто, но нарушает передовую практику лямбда-выражений. Код становится раздутым.
Мы перемещаем try, catch в метод-оболочку:
static Consumer<Integer> lambdaWrapper(Consumer<Integer> consumer) {
return i -> {
try {
consumer.accept(i);
} catch (ArithmeticException e) {
System.err.println(
"Arithmetic Exception occured : " + e.getMessage());
}
};
}
Первоначальный вызов становится таким:
integers.forEach(lambdaWrapper(i -> System.out.println(1 / i)));
Но обертка выше исправила отлов ArithmeticException, давайте адаптируем его к более общему классу:
static <T, E extends Exception> Consumer<T>
consumerWrapperWithExceptionClass(Consumer<T> consumer, Class<E> clazz) {
return i -> {
try {
consumer.accept(i);
} catch (Exception ex) {
try {
E exCast = clazz.cast(ex);
System.err.println(
"Exception occured : " + exCast.getMessage());
} catch (ClassCastException ccEx) {
throw ex;
}
}
};
}
Вышеупомянутый класс передает класс и приводит его к исключению, если он может быть приведен, обрабатывает его, в противном случае генерирует исключение.
После этого мы вызываем его так:
integers.forEach(
consumerWrapperWithExceptionClass(
i -> System.out.println(1 / i),
ArithmeticException.class));
Обработка отмеченных исключений
Checked Exception — это исключение, которое необходимо обработать.Давайте рассмотрим пример:
static void throwIOException(Integer integer) throws IOException {
}
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
integers.forEach(i -> throwIOException(i));
Выше мы определили метод, который генерирует IOException, которое является проверенным исключением и требует обработки, поэтому в следующем forEach программа не скомпилируется, поскольку соответствующее исключение не обрабатывается.
Самый простой способ - попробовать и поймать, следующим образом:
integers.forEach(i -> {
try {
throwIOException(i);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
Конечно, недостатки этого подхода были упомянуты выше, аналогично мы можем определить новый метод-оболочку:
static <T> Consumer<T> consumerWrapper(
ThrowingConsumer<T, Exception> throwingConsumer) {
return i -> {
try {
throwingConsumer.accept(i);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
};
}
Мы называем это так:
integers.forEach(consumerWrapper(i -> throwIOException(i)));
Мы также можем посмотреть на исключение пакета:
static <T, E extends Exception> Consumer<T> consumerWrapperWithExceptionClass(
ThrowingConsumer<T, E> throwingConsumer, Class<E> exceptionClass) {
return i -> {
try {
throwingConsumer.accept(i);
} catch (Exception ex) {
try {
E exCast = exceptionClass.cast(ex);
System.err.println(
"Exception occured : " + exCast.getMessage());
} catch (ClassCastException ccEx) {
throw new RuntimeException(ex);
}
}
};
}
Затем вызовите так:
integers.forEach(consumerWrapperWithExceptionClass(
i -> throwIOException(i), IOException.class));
Суммировать
В этой статье рассказывается, как обрабатывать проверенные и непроверенные исключения в лямбда-выражениях, и я надеюсь, что она поможет вам.
Примеры этой статьиGitHub.com/Dadean2009/приходите…
Добро пожаловать, обратите внимание на мой публичный номер: вас ждут самые интересные вещи о программе! Для получения дополнительной информации, пожалуйста, посетитеwww.flydean.com