В чем разница между методами-близнецами в 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 »).
Это предположение верно?
Есть ли какие-то другие тонкие коннотации в двух способах ведения дел?




Если AnException - это проверенное исключение (другими словами, если оно не расширяет RuntimeException), то methodA не будет компилироваться. Проверенные исключения всегда нужно объявлять.
Если AnException является непроверенным исключением (если оно расширяет RuntimeException), то либо компилятор java разрешает, либо интерпретирует эквивалентно средой выполнения java. МетодA, вероятно, по-прежнему предпочтительнее в этом случае по причинам документации. Документация javadoc для вашего метода покажет, что он может вызвать исключение AnException. Хорошо, если пользователи вашего метода знают, каких исключений им следует ожидать.
Во втором методе класс 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-)
Вы не можете объявлять или выдавать дополнительные проверенные исключения. Однако вы можете генерировать дополнительные необъявленные непроверенные исключения и ошибки.
Непроверенные исключения и ошибки должны выдаваться без объявления и представлять ситуации, когда у используемого кода нет жизнеспособных вариантов обработки, а приложение должен аварийно завершает работу. Это всегда верно, и это не имеет ничего общего с методами переопределения. = 8-)
Кажется, вы ссылаетесь на оба примера как на «methodA», что несколько сбивает с толку.