Почему Java multi-catch не может работать с типами, связанными с использованием подклассов?

Вот фрагмент кода, который не должен компилироваться:

void multiCatch()
{
    try {
        throwIOFile();
    }
    // FileNotFoundException extends IOException, hence this
    // does not compile ("alternatives" related by sub classing):
    catch (IOException | FileNotFoundException e) { }
}

void throwIOFile() throws IOException, FileNotFoundException
{}

Все работает как очарование, если бы не типы исключений были связаны подклассами. Если вы поменяете IOException в моем фрагменте кода, скажем.. SQLException, оно работает. Спецификация гласит:

Это ошибка времени компиляции, если объединение типов содержит две альтернативы Di и Dj (i ≠ j), где Di является подтипом Dj.

Я не могу понять обоснование этого. Конечно, multi-catch в моем примере полностью избыточен, так как я мог бы также поймать IOException только. Но что может быть вредным в том, чтобы сделать мой фрагмент кода легальным? Конечно, должен быть вред, чтобы практика стала незаконной?

3 ответа

Решение

В спецификации обсуждается, что

Предложение multi-catch можно рассматривать как последовательность предложений uni-catch

так что ваш код вроде

    try {
        throwIOFile();
    }
    catch (IOException e) { }
    catch (FileNotFoundException e) { }  // error

Это также отвергается Javac. В этом случае ошибка оправдана, так как 2-е предложение недоступно.


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

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

catch (IOException | FileNotFoundException e)

если

catch (IOException e)

будет иметь точно такое же поведение? Это просто сбивает с толку.

Но что может быть вредным в том, чтобы сделать мой фрагмент кода легальным? Конечно, должен быть вред, чтобы практика стала незаконной?

Это сбивает с толку код - вы можете упростить код, просто ловя IOExceptionв то время как, похоже, вам действительно нужно поймать их обоих по отдельности.

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

Другие вопросы по тегам