Использование троичного оператора для создания проверенных или непроверенных исключений - PullRequest
7 голосов
/ 01 мая 2019

В моем исходном вопросе использовались FileNotFoundException и IllegalStateException, и поэтому они включены в ответ.Я заменил их на суперклассы IOException и RuntimeException соответственно для простоты.


Это компилирует (без использования троичного, 1 проверено, 1 не проверено):

private void test() throws IOException { // throws is required
    if (new Random().nextInt(2)==0) throw new IOException();
    throw new RuntimeException();
}

Это также компилирует (используя троичное, 2 непроверенных исключения):

private void test3() { // throws not required
    throw new Random().nextInt(2)==0 ? new UncheckedIOException(null) : new RuntimeException();
}

Но почему это не компилируется (используя троичное, 1 проверено, 1 непроверено)?

private void test2() throws IOException {
    throw new Random().nextInt(2)==0 ? new IOException() : new RuntimeException();
}

Из Eclipse:

Необработанный тип исключения Исключение

Доступны 2 быстрых исправления:

J! Добавить объявление бросков

J! Окружить с помощьюtry / catch


Другая пара примеров

Это компилируется:

private void test4() { // throws not required
    if (new Random().nextInt(2)==0) throw new Error();
    throw new RuntimeException();
}

Это не:

private void test5() {
    throw new Random().nextInt(2)==0 ? new Error() : new RuntimeException();
}

Из Eclipse:

Необработанный тип исключения Throwable

Доступны 2 быстрых исправления:

J! Добавить объявление бросков

J! Окружить с помощьюпопробуй / поймай

1 Ответ

13 голосов
/ 01 мая 2019

Почему это не компилируется?

Поскольку предполагаемый тип условного оператора?: В этом случае равен Exception, следуя правилам JLS 15.25.3 . Хотя JLS очень быстро усложняется, правила пытаются найти «наиболее конкретный тип, где есть неявное преобразование из обоих типов операндов». Этакий «ближайший общий предок».

Иерархия наследования в этом случае:

                      Exception
                   /              \
           IOException           RuntimeException
               /                         \
      FileNotFoundException           IllegalStateException

... так что ближайший общий предок - Exception. Ваш код в некоторой степени эквивалентен:

private void test() throws FileNotFoundException {
    Exception exception = 1==0 ? new FileNotFoundException() : new IllegalStateException();
    throw exception;
}

Надеюсь, вы уже понимаете, почему , что не скомпилируется ... в этом случае, если повезет, теперь все ясно:)

...