Немного предыстории, потом вопросы.
Я только недавно обнаружил, что интерфейс (или класс) может быть универсальным по типу (проверенного) исключения, которое могут генерировать его методы. Например:
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
бросаетIOException
(возможно,ByteArrayOutputStream
может протягиватьGenericOutputStream<RuntimeException>
)Callable
/Future.get
Общественный пул
borrowObject
/makeObject
(После редактирования я не спрашиваю, могли ли/должны ли они быть спроектированы по-другому в ретроспективе. Скорее, будет ли throws X
лучше, чем throws Exception
.)
Throwables
в Guava есть некоторые Примеры. Но этот вопрос кажется слишком широким. Постарайтесь усовершенствовать свои различные вопросы в посте, сделав их более сфокусированными. - person Paul Bellora   schedule 09.02.2014