Подтвердить что ты не робот

Есть ли способ сделать Runnable run() для исключения?

Метод, который я вызываю в run() в классе, который реализует Runnable) предназначен для исключения исключений.

Но компилятор Java не позволит мне это сделать и предлагает, чтобы я окружал его с помощью try/catch.

Проблема заключается в том, что, окружив ее try/catch, я делаю эту run() бесполезной. Я хочу исключить это исключение.

Если я укажу throws для run() сам, компилятор жалуется, что Exception is not compatible with throws clause in Runnable.run().

Как правило, я в полном порядке, не позволяя run() вызывать исключение. Но у меня есть уникальная ситуация, когда у меня должна быть эта функциональность.

Как мне обойти это ограничение?

4b9b3361

Ответ 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.