Некоторые предпосылки, затем некоторые вопросы.
Я только недавно обнаружил, что интерфейс (или класс) может быть общим в типе (проверенном) исключении, которое могут вызвать его методы. Например:
interface GenericRunnable<X extends Exception> {
void run() throws X;
}
Дело в том, что если позже вы создадите экземпляр с помощью, скажем, IOException
и вызовите метод run
, компилятор знает, что вам нужно либо поймать IOException
, либо пометить его как брошенное. Еще лучше, если X
был RuntimeException
, вам вообще не нужно его обрабатывать.
Здесь надуманный пример с использованием вышеприведенного интерфейса, но он в основном обратный вызов и должен быть довольно распространенным.
public <X extends Exception> void runTwice(GenericRunnable<X> runnable) throws X {
runnable.run(); runnable.run();
}
...
public myMethod() throws MyException {
runTwice(myRunnable);
}
Мы вызываем общий метод утилиты runTwice
(возможно, определенный во внешней библиотеке) для запуска нашего собственного метода с определенным проверенным исключением, и мы не теряем информацию о том, какое конкретное исключенное исключение может быть выбрано.
Альтернативой было бы просто использовать throws Exception
как для метода Runnable.run
, так и для метода runTwice
. Это не будет ограничивать реализацию интерфейса Runnable
, но преимущество проверенных исключений будет потеряно. Или вообще не могло быть throws
, также теряя преимущество проверенных исключений и потенциально заставляя реализацию обернуть.
Потому что я никогда не видел throws X
, возможно, я что-то пропустил. Кроме того, я видел пример обратного вызова, который использовался как аргумент против отмеченных исключений несколько раз, без его опровержения. (Этот вопрос не интересует плюсы и минусы проверенных исключений.)
Является ли throws X
хорошей идеей? Каковы плюсы и минусы? Можете ли вы привести несколько примеров, которые либо используют throws X
, либо не должны, но должны иметь?
В принципе, я хотел бы получить дополнительную информацию. Вы можете прокомментировать следующие примеры.
-
OutputStream
throwsIOException
(возможно,ByteArrayOutputStream
может расширятьGenericOutputStream<RuntimeException>
) -
Callable
/Future.get
-
Commons Pool
borrowObject
/makeObject
(Начиная с редактирования, я не прошу, чтобы они могли/должны были быть спроектированы по-разному ретроспективно. Скорее, throws X
был бы лучше, чем throws Exception
.)