Есть ли способ сделать Runnable run() для исключения?
Метод, который я вызываю в run() в классе, который реализует Runnable) предназначен для исключения исключений.
Но компилятор Java не позволит мне это сделать и предлагает, чтобы я окружал его с помощью try/catch.
Проблема заключается в том, что, окружив ее try/catch, я делаю эту run() бесполезной. Я хочу исключить это исключение.
Если я укажу throws
для run() сам, компилятор жалуется, что Exception is not compatible with throws clause in Runnable.run()
.
Как правило, я в полном порядке, не позволяя run() вызывать исключение. Но у меня есть уникальная ситуация, когда у меня должна быть эта функциональность.
Как мне обойти это ограничение?
Ответы
Ответ 1
Если вы хотите передать класс, который реализует Runnable
в структуру Thread
, тогда вы должны играть по этим правилам фреймворка, см. вопрос Эрнеста Фридмана-Хилла, почему делать это в противном случае - плохая идея.
У меня есть подозрение, что вы хотите вызвать метод run
непосредственно в вашем коде, поэтому ваш код вызова может обрабатывать исключение.
Ответ на эту проблему прост. Не используйте Runnable
интерфейс из библиотеки Thread, но вместо этого создайте свой собственный интерфейс с модифицированной сигнатурой, которая позволяет исключить проверенное исключение, например.
public interface MyRunnable
{
void myRun ( ) throws MyException;
}
Вы даже можете создать адаптер, который преобразует этот интерфейс в реальный Runnable
(путем обработки исключенного исключения), подходящего для использования в структуре Thread.
Ответ 2
Вместо этого вы можете использовать Callable
, отправив его в ExecutorService
и ожидая результата с FutureTask.isDone()
, возвращаемым ExecutorService.submit()
.
Когда isDone()
возвращает true, вы вызываете FutureTask.get()
. Теперь, если ваш Callable
сбросил Exception
, тогда FutureTask.get()
запустит Exception
и исходное исключение, с которым вы сможете получить доступ, используя Exception.getCause()
.
Ответ 3
Если run()
выбрал исключенное исключение, что бы его поймать? Вам не нужно заключать этот вызов run()
в обработчик, так как вы не записываете код, который его вызывает.
Вы можете поймать выбранное исключение в методе run()
и выбросить исключенное исключение (т.е. RuntimeException
) на свое место. Это приведет к завершению потока с трассировкой стека; возможно, что вы после.
Если вместо этого вы хотите, чтобы ваш метод run()
сообщал об ошибке где-то, вы можете просто предоставить метод обратного вызова для run()
метода catch
для вызова; этот метод может хранить объект исключения где-то, а затем ваш заинтересованный поток может найти объект в этом месте.
Ответ 4
Да, есть способ выбросить проверенное исключение из метода run()
, но это так ужасно, что я не буду делиться им.
Здесь вы можете сделать это; он использует тот же механизм, что и исключение во время выполнения:
@Override
public void run() {
try {
/* Do your thing. */
...
} catch (Exception ex) {
Thread t = Thread.currentThread();
t.getUncaughtExceptionHandler().uncaughtException(t, ex);
}
}
Как отмечали другие, если ваш метод run()
действительно является мишенью для Thread
, нет смысла бросать исключение, потому что оно ненаблюдаемо; бросание исключения имеет тот же эффект, что и исключение исключения (none).
Если это не цель Thread
, не используйте Runnable
. Например, возможно Callable
лучше подходит.
Ответ 5
Ваше требование не имеет никакого смысла. Если вы хотите уведомить вызванный поток о произошедшем исключении, вы можете сделать это через механизм обратного вызова. Это может быть через обработчик или трансляцию или что-то еще, что вы можете придумать.
Ответ 6
Я думаю, что шаблон прослушивателя может помочь вам в этом сценарии. В случае возникновения исключения в вашем методе run()
используйте блок try-catch и в catch поймите уведомление об исключении. Затем обработайте событие уведомления. Я думаю, что это будет более чистый подход. Эта ссылка SO дает вам полезный указатель на это направление.
Ответ 7
Самый простой способ - определить свой собственный объект исключения, который расширяет класс RuntimeException
вместо класса Exception
.