Вебинары Разобраться в IT Реферальная программа
Программирование Аналитика Дизайн Маркетинг Управление проектами
14 Фев 2023
2 мин
108

Бросание проверяемых исключений внутри лямбд и потоков в Java 8

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

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

Представим типичную ситуацию. Например, необходимо преобразовать список названий классов в список объектов Class с помощью потока и функции Class.forName(). Эта функция может бросить ClassNotFoundException, который является проверяемым исключением.

public List<Class> getClasses() throws ClassNotFoundException {     

    List<Class> classes = 
        Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
              .map(className -> Class.forName(className))
              .collect(Collectors.toList());                  
    return classes;
}

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

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

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

@FunctionalInterface
public interface ThrowingFunction<T, R, E extends Exception> {
    R apply(T t) throws E;
}

Теперь можно использовать этот интерфейс вместе с потоком и лямбда-выражением:

public List<Class> getClasses() throws ClassNotFoundException {     

    ThrowingFunction<String, Class, ClassNotFoundException> mapFunction = className -> Class.forName(className);

    List<Class> classes = 
        Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
              .map(mapFunction)
              .collect(Collectors.toList());                  
    return classes;
}

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

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей

Добавить комментарий