Java 8 - выбрасывать несколько общих проверенных исключений в лямбду - PullRequest
0 голосов
/ 28 сентября 2018

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

public void method1() throws ExceptionA {
    String exceptionString = "";
    try {
        super.method1();
    } catch (ExceptionA e) {
         exceptionString = // <convert the exception to string in an elaborate way>
         throw e;
    } finally {
         // <an elaborate logger call which uses value of exceptionString>
    }
}

public void method2() throws ExceptionB, ExceptionC {
    String exceptionString = "";
    try {
        super.method2();
    } catch (ExceptionB | ExceptionC e) {
         exceptionString = // <convert the exception to string in elaborate way>
         throw e;
    } finally {
         // <an elaborate logger call which uses value of exceptionString>
    }
}

// ... <a bunch of other methods like this>

Я сразу же подумал: «Ух ты, как может быть иметь одну универсальную оболочку и просто вызывать ее в каждом из этих методов. Класс будет примерно в 10 раз короче!»,Итак, я приступил к работе.

Вот где я застрял:

private interface ThrowingMethod<E extends Exception> {
    void run() throws E;
}

public <E extends Exception> void wrapMethod(ThrowingMethod<E> method) throws E {
    String exceptionString = "";
    try {
        method.run();
    } catch (Exception e) {
         exceptionString = // <convert the exception to string in an elaborate way>
         throw e;
    } finally {
         // <an elaborate logger call which uses value of exceptionString>
    }
}

public void method1() throws ExceptionA {
    wrapMethod(super::method1); // works
}

public void method2() throws ExceptionB, ExceptionC {
    wrapMethod(super::method2); // Error in Eclipse: "Unhandled exception type Exception"
}

// ... <a bunch of other methods like this>

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

Я пытался добавить более общие параметры в ThrowingMethod и wrapMethod, но это ничего не меняет.

Как получить функциональный интерфейс для работы с несколькими общими исключениями?

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Когда вы расширяете свой интерфейс для использования двух переменных типа, то есть

private static interface ThrowingMethod<E1 extends Exception,E2 extends Exception> {
    void run() throws E1, E2;
}

public <E1 extends Exception,E2 extends Exception>
void wrapMethod(ThrowingMethod<E1,E2> method) throws E1,E2 {
    // same as before
}

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

public void method1() throws ExceptionA {
    wrapMethod(super::method1);
}

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

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

Но вы можете помочь компилятору в этом случае, например,

public void method2() throws ExceptionB, ExceptionC {
    wrapMethod((ThrowingMethod<ExceptionB, ExceptionC>)super::method2);
}

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

0 голосов
/ 28 сентября 2018

Итак, ваша цель состоит в том, чтобы обернуть кучу методов в логирование?Типичный способ справиться с этим - AOP .Вы просто создали бы один pointcut, который соответствует всем этим методам, и у вас не было бы множества повторяющихся шаблонов.Нет необходимости в этих интерфейсах или методах упаковки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...