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

醜い(賢い?)ハックを使用して、スロー可能な例外をチェックされていない例外に変換することができます。利点は、チェックされているかどうかに関係なく、呼び出し元のコードがワーカースレッドによってスローされた例外を受け取ることですが、メソッドのシグネチャを変更する必要はありません。

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 に答える