java 处理 ExecutionException 的原因

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14729834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 17:10:41  来源:igfitidea点击:

Handling the cause of an ExecutionException

javaswingworkerexecutionexception

提问by DieterDP

Suppose I have a class defining a big block of work to be done, that can produce several checked Exceptions.

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

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

Now suppose I have a GUI of some sort that can call this class. I use a SwingWorker to delegate the task.

现在假设我有一个可以调用这个类的 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);
        }
};

How can I handle the possible exceptions thrown from the SwingWorker? I want to differentiate between the Exceptions of my worker class (InvalidInputException and MiscalculationException), but the ExecutionException wrapper complicates things. I only want to handle these Exceptions - an OutOfMemoryError should not be caught.

如何处理从 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.

采纳答案by Mikhail Vladimirov

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
}

回答by assylias

You could use an ugly (smart?) hackto convert the throwable into an unchecked exception. The advantage is that the calling code will receive whatever exception was thrown by your worker thread, whether checked or unchecked, but you don't have to change the signature of your method.

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

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

With UncheckedThrowerdefined as:

随着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;
    }
}

回答by Doorknob

Try/multi-catch:

尝试/多次捕获:

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

Or with the ExecutionExceptionwrapper:

或者使用ExecutionException包装器:

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

Or if you want exceptions' subclasses to be treated like their parents:

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

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