2009-06-30 13 views
0

Javaの匿名クラスから出力を取得するにはどうすればよいですか? .NETではクロージャを使用します。匿名クラスからの出力?

executor = Executors.newSingleThreadExecutor(); 
final Runnable runnable = new Runnable() { 
    public Exception exception; 

    @Override 
    public void run() { 
    try { 
     doSomething(); 
    } 
    catch (Exception exception) { 
     // I'd like to report this exception, but how? 
     // the exception member is not readable from outside the class (without reflection...) 
     this.exception = exception; 
    } 
    } 
}; 

executor.submit(runnable); 

// Here I'd like to check if there was an exception 

答えて

7

Executorインターフェイスではこれを行う方法がありません。ただし、newSingleThreadExecutor()に電話すると、その機能を含むExecutorServiceが表示されます。

ExecutorService.submit()を呼び出すと、Future<?>のインスタンスが返されます。これを使用して計算の結果値を取得できます。

実行で例外が発生した場合は、getを呼び出すとExecutionExceptionがスローされます。

+0

私はRunnableを使用しないでください。 – ripper234

+0

結果を得たい場合は、Callableを使用する必要があります。 Runnableからの結果として値を返す方法はありません(IIRCはrunnablesがnullを返すために 'get'を呼び出します) – andri

+0

むしろ、正しく実行したいタスクは戻り値がありませんが、例外について通知したいと思います。 Runnable.run()は例外を宣言しないので、使用できません。 Callableは何かを返す必要があります。 私は、呼び出し可能な例外を返すことができますが、それは少し最適ではないようです。理想的には、 '同等の実行'が例外をスローすることができますが、voidを返す別の同様のクラスが必要です。しかたがない。 – ripper234

-2

例外をfinal宣言した場合、匿名クラスはそこに値を格納でき、run()が完了すると変数をチェックできます。

編集に追加:申し訳ありませんが、私はそれを1つの例外の最終配列にするつもりです。アイデアはこれを自動的に行いますので、余分なリダイレクトを忘れることがよくあります。

final Exception[] except;

+0

私はこれが正しいとは思わない。例外が宣言された場合、最終的な変更はできませんので、クラスのrun()メソッドから例外を更新することはできません。 – Adamski

2

あなたの代わりにRunnableをのCallableを使用したいエグゼキュータで実行するタスクから例外を取得するには。

Callableのcall()メソッドは、チェックされた例外をスローできます。 Futureインスタンスでget()を呼び出すと、call()メソッドによってチェックされた例外がスローされた場合、ExecutionExceptionがスローされます。 ExecutionExceptionでgetCause()を呼び出すことによって、基礎となるチェック例外にアクセスできます。

+0

この回答は真実です。 Runnableを含むハックなソリューションを提供する他の答えは無視する必要があります。このタイプの問題の標準的なイディオムは、RunableではなくCallableを使用することです。 – Adamski

+0

+1;これはCallableが発明されたものです。 –

+0

Callableは出力を取得するためのものです。そのため、例外をエラーを示す戻り値に変換したい場合は、最初に例外ポイントを破棄してからCallable が適切です。または、ライブラリで与えられたメカニズムを使用するだけです。Runnableを入れると、将来のが返され、値を取得すると例外が返されます。 –

0

あなたはRunnableをあなたははRuntimeExceptionであなたのスローされた例外をラップし、あなたにexecutor.submit()電話を置くことができる例外

public class Driver { 
static Exception exec; 
static final Runnable runnable = new Runnable() { 
    public Exception exception; 

    public void run() { 
     try { 
      throw new Exception("asdf"); 
     } 
     catch (Exception exception) { 
      exec = exception; 
     } 
    } 
    }; 

public static void main(String[] args) throws Exception{ 
    ExecutorService e = Executors.newSingleThreadExecutor(); 
    e.submit(runnable); 
    e.shutdown(); 
    while(e.isShutdown()==false){ 
     Thread.sleep(2000); 
    } 
    System.out.println(exec); 

} 
0

を報告するために呼び出す静的変数/メソッドを持つことができ、ハック....しかし、 try/catchブロック:

executor = Executors.newSingleThreadExecutor(); 
final Runnable runnable = new Runnable() { 

@Override 
    public void run() { 
    try { 
    doSomething(); 
    } catch (Exception exception) { 
     throw new RuntimeException(exception); 
    } 
    } 
}; 

try{ 
executor.submit(runnable); 
} catch (Throwable t) { 
    Throwable cause = t.getCause(); 
    //do what you want with the cause 
}