7

假设我有一个类定义了一大块要完成的工作,它可以产生几个检查异常。

class WorkerClass{
   public Output work(Input input) throws InvalidInputException, MiscalculationException {
      ...
   }
}

现在假设我有某种可以调用此类的 GUI。我使用 SwingWorker 来委派任务。

Final Input input = getInput();
SwingWorker<Output, Void> worker = new SwingWorker<Output, Void>() {
        @Override
        protected Output doInBackground() throws Exception {
            return new WorkerClass().work(input);
        }
};

如何处理 SwingWorker 抛出的可能异常?我想区分我的工人类的异常(InvalidInputException 和 MiscalculationException),但是 ExecutionException 包装器使事情变得复杂。我只想处理这些异常——不应捕获 OutOfMemoryError。

try{
   worker.execute();
   worker.get();
} catch(InterruptedException e){
   //Not relevant
} catch(ExecutionException e){
   try{
      throw e.getCause(); //is a Throwable!
   } catch(InvalidInputException e){
      //error handling 1
   } catch(MiscalculationException e){
      //error handling 2
   }
}
//Problem: Since a Throwable is thrown, the compiler demands a corresponding catch clause.
4

3 回答 3

8
catch (ExecutionException e) {
    Throwable ee = e.getCause ();

    if (ee instanceof InvalidInputException)
    {
        //error handling 1
    } else if (ee instanceof MiscalculationException e)
    {
        //error handling 2
    }
    else throw e; // Not ee here
}
于 2013-02-06T13:13:22.987 回答
1

您可以使用丑陋的(智能?)hack将 throwable 转换为未经检查的异常。优点是调用代码将接收工作线程抛出的任何异常,无论是选中的还是未选中的,但您不必更改方法的签名。

try {
    future.get();
} catch (InterruptedException ex) {
} catch (ExecutionException ex) {
    if (ex.getCause() instanceof InvalidInputException) {
        //do your stuff
    } else {
        UncheckedThrower.throwUnchecked(ex.getCause());
    }
}

定义UncheckedThrower为:

class UncheckedThrower {

    public static <R> R throwUnchecked(Throwable t) {
        return UncheckedThrower.<RuntimeException, R>trhow0(t);
    }

    @SuppressWarnings("unchecked")
    private static <E extends Throwable, R> R trhow0(Throwable t) throws E {
        throw (E) t;
    }
}
于 2013-02-06T13:15:38.500 回答
0

尝试/多次捕获:

try {
    worker.execute();
    worker.get();
} catch (InterruptedException e) {
    //Not relevant
} catch (InvalidInputException e) {
    //stuff
} catch (MiscalculationException e) {
    //stuff
}

或者使用ExecutionException包装器:

catch (ExecutionException e) {
    e = e.getCause();
    if (e.getClass() == InvalidInputException.class) {
        //stuff
    } else if (e.getClass() == MiscalculationException.class) {
        //stuff
    }
}

或者,如果您希望将异常的子类视为其父类:

catch (ExecutionException e) {
    e = e.getCause();
    if (e instanceof InvalidInputException) {
        //stuff
    } else if (e instanceof MiscalculationException) {
        //stuff
    }
}
于 2013-02-06T13:08:15.420 回答