Почему нельзя проверять исключения в потоке Java на уровне метода? - PullRequest
0 голосов
/ 11 ноября 2018

Я изучал параллелизм и потоки API и натолкнулся на это. Метод offerLast() может выдать InterruptedException, поэтому я понимаю, что должен с этим справиться. Чего я не понимаю - почему я не могу выбросить его на уровне метода, добавив throws Exception ?. Так как это code не компилируется.

static BlockingDeque<Integer> queue = new LinkedBlockingDeque<>();

public static void testing() throws Exception {
    IntStream.iterate(1, i -> i+1).limit(5)
            .parallel()
            .forEach(s -> queue.offerLast(s, 10000, TimeUnit.MILLISECONDS));
}

Я знаю, что это можно решить, окружив его try/catch или создав wrapper method, который обрабатывает error, но я все еще пытаюсь понять, почему его нельзя бросить в метод уровень.

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Простой ответ заключается в том, что «метод», на который вы ссылаетесь, это Consumer.accept, а не YourClass.testing.

Лямбда s -> queue.offerLast(s, 10000, TimeUnit.MILLISECONDS) является реализацией java.util.function.Consumer.accept(T), которая не объявляет, что может выдавать InterruptedException.
И это поведение не относится к потокам, где бы ни определялось лямбда-выражение, оно должно соответствовать сигнатуре абстрактного метода реализуемого им функционального интерфейса.

0 голосов
/ 11 ноября 2018

Поскольку лямбда-выражения не всегда вычисляются сразу.

Пусть у вас есть это:

public Supplier<String> giveMeASupplier() throws Exception {
    return () -> someMethodThatThrowsCheckedException()
}

По вашему мнению, вышесказанное сработает. Правильно?

Теперь другим способом я могу сделать это:

Suppler<String> supplier = null;
try {
    supplier = giveMeASupplier() // no exception is thrown here.
} catch (Exception ex) {
    ex.printStackTrace();
}
if (supplier != null) {
    System.out.println(supplier.get()); // this might throw an exception! Yet it's not in a try...catch!
}

Как вы думаете, что произойдет, если supplier.get() сгенерирует исключение? Есть что-нибудь, чтобы поймать это? Нет. Если каким-то образом блок catch за несколько строк до запуска будет запущен, то это будет действительно странно.

...