Исключения с объявлением и выбросом против исключения без объявления

В чем разница между методами-близнецами в Java?

public void methodA() throws AnException {
    //do something
    throw new AnException();
}

public void methodA() {
    //do the same thing
    throw new AnException();
}

У меня есть интуиция, что это как-то связано с тем, что это хорошо спроектированный метод (потому что я поместил methodA в интерфейс, объявил его так, как это делает methodA * в своей реализации, и получил предупреждение от Java, что «A * не может переопределить A, потому что A * не генерирует исключение AnException »).

Это предположение верно?

Есть ли какие-то другие тонкие коннотации в двух способах ведения дел?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
9
0
9 189
5

Ответы 5

Если AnException - это проверенное исключение (другими словами, если оно не расширяет RuntimeException), то methodA не будет компилироваться. Проверенные исключения всегда нужно объявлять.

Если AnException является непроверенным исключением (если оно расширяет RuntimeException), то либо компилятор java разрешает, либо интерпретирует эквивалентно средой выполнения java. МетодA, вероятно, по-прежнему предпочтительнее в этом случае по причинам документации. Документация javadoc для вашего метода покажет, что он может вызвать исключение AnException. Хорошо, если пользователи вашего метода знают, каких исключений им следует ожидать.

Кажется, вы ссылаетесь на оба примера как на «methodA», что несколько сбивает с толку.

Stephan 25.11.2013 10:07

Во втором методе класс AnException должен быть подклассом RuntimeException, что означает, что объявление не является обязательным и вызывающие методы не должны его обрабатывать. Примером RuntimeException является ArrayOutOfBoundException, представьте, если бы вы явно обрабатывали исключение (путем объявления throw или с помощью блока try / catch) каждый раз, когда вы используете List.

По чисто документационным причинам хорошо, что исключение включено в определение функции. Таким образом, вызывающим абонентам ясно, какие исключения необходимо обработать. Я также предполагаю, что компилятору необходимо выполнить некоторые дополнительные настройки для функций, которые генерируют исключения.

Первый метод должен быть вызван в блоке try catch или в объявлении метода возникает исключение. в противном случае компиляция не удастся.

У второго такого ограничения нет

Помимо хороших ответов, данных другими о компилируемости ваших методов как таковых, существует проблема реализации интерфейсов и переопределения методов в суперклассах.

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

Допустим, вы используете какую-то структуру данных:

public abstract class AbstractBox {
  public abstract void addItem(Item newItem);
  public abstract void removeItem(Item oldItem);
}

У вас есть собственная реализация, но вы решили объявить исключения, которых нет в исходной подписи:

public class MyBox extends AbstractBox {
  public void addItem(Item newItem) throws ItemAlreadyPresentException {...}
  public void removeItem(Item oldItem) throws NoSuchItemException {...}
}

Теперь давайте рассмотрим этот общий код, который обрабатывает объекты Box и получает экземпляр MyBox:

public void boxHandler(AbstractBox box) {
  Item item = new Item();
  box.removeItem(item);
}

Тот, кто писал этот код, не ожидал никаких исключений и не собирался обрабатывать исключения разработчика. Чтобы предотвратить это, компилятор не позволит вам объявлять дополнительные исключения к исключениям в исходной подписи.

Конечно, если вы обрабатываете исключения внутри себя ... ну, компилятор будет более чем счастлив позволить вам удалить объявленные исключения из вашей подписи ;-)

Надеюсь это поможет...

Юваль = 8-)

Вы не можете объявлять или выдавать дополнительные проверенные исключения. Однако вы можете генерировать дополнительные необъявленные непроверенные исключения и ошибки.

Peter Lawrey 22.03.2009 22:55

Непроверенные исключения и ошибки должны выдаваться без объявления и представлять ситуации, когда у используемого кода нет жизнеспособных вариантов обработки, а приложение должен аварийно завершает работу. Это всегда верно, и это не имеет ничего общего с методами переопределения. = 8-)

Yuval 23.03.2009 11:12

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