Некоторые предпосылки, затем некоторые вопросы.Хороший шаблон? <X extends Exception> ... method() throws X
Я только недавно обнаружил, что интерфейс (или класс) может быть общим в типе (отмеченного) исключения, которое могут быть выбраны его методы. Например:
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
(С Editi Я не спрашиваю, могли ли они/должны были быть разработаны по-разному в ретроспективе. Скорее, throws X
будет лучше, чем throws Exception
.)
Класс потоков не мог быть спроектирован так, потому что они были разработаны до того, как эта функция была добавлена (т. Е. Дженерики). – tbodt
У Guava ['Throwables'] (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Throwables.html) есть несколько примеров. Но этот вопрос кажется слишком широким. Постарайтесь усовершенствовать свои различные вопросы на протяжении всего поста в нечто более целенаправленное. –
Да. Java развивается со временем. Это означает, что всегда есть места в старых классах/функциях, где более новые были использованы, но не были доступны, и, поскольку все работает достаточно хорошо без них, для этого не было достаточного оправдания , Вы можете, конечно, реализовать свои собственные обертки/повторные применения старых классов, чтобы использовать новые функции, и если они действительно окажутся достаточно полезными, они могут быть приняты; что на самом деле является частью того, как выросли библиотеки Java. Но это происходит только при наличии достаточной реальной добавленной стоимости и достаточного спроса, чтобы оправдать ее. – keshlam