Правильное использование лямбда-выражения с помощью необязательного # orElseThrow - PullRequest
0 голосов
/ 14 февраля 2019

Рассмотрим следующий простой пример:

Optional.empty().orElseThrow(this::exceptionSupplier);

IntelliJ генерирует для поставщика метод, подобный следующему, хотя он не компилируется!

private <X extends Throwable> X exceptionSupplier() {
    return new RuntimeException();
}

Несовместимые типы.Требуется: X Найдено: java.lang.RuntimeException

Если я изменю подпись на следующую, она будет работать.

private Exception exceptionSupplier() {
    return new RuntimeException();
}

Правильно ли, что компилятор не может определить правильный тип для X * * 1013

1 Ответ

0 голосов
/ 14 февраля 2019

Если первый пример сработает, рассмотрите следующее:

Supplier<InterruptedException> s = this::exceptionSupplier;

В таком случае произойдет сбой с ClassCastException, если вы назвали его так:

InterruptedException e = s.get();

Этопотому что X определяется на сайте вызова.Компилятор вставляет неявное приведение:

InterruptedException e = (InterruptedException) s.get();

Но, конечно, s возвращает вам RuntimeException, который не может быть приведен к InterruptedException.

Если вы хотите вернуть RuntimeException, сделайте тип возврата метода RuntimeException, переменная типа не требуется.

...