Domanda

Come posso ottenere l'uscita dal Java classi anonime? In .Net Vorrei usare le chiusure.

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
È stato utile?

Soluzione

La Executor interfaccia offre alcun modo per farlo. Tuttavia, quando si chiama newSingleThreadExecutor() si otterrà un ExecutorService che contiene la funzionalità per questo.

La chiamata ExecutorService.submit() restituisce un'istanza di Future<?> , che è possibile utilizzare per ottenere il valore del risultato del calcolo.

Se l'esecuzione ha provocato un'eccezione, chiamando get causerà un ExecutionException per essere gettato.

Altri suggerimenti

Per ottenere una deroga l'esecuzione di un'attività su un esecutore che si desidera utilizzare richiamabile invece di Runnable.

Il metodo call () di Callable può lanciare eccezioni controllate. Quando si chiama get () sul tuo Future istanza si getterà un ExecutionException se il metodo di chiamata () ha gettato un eccezione controllata. È quindi possibile accedere alla eccezione controllata sottostante chiamando getCause () sul ExecutionException.

Hackish .... ma, si potrebbe avere una variabile / metodo statico che il Runnable chiama per segnalare l'eccezione

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);

}

Si potrebbe avvolgere l'eccezione generata in un RuntimeException e mettere il vostro executor.submit() chiamata in un blocco 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
}

Se si dichiara l'eccezione di essere definitiva, la classe anonima sarà in grado di memorizzare il valore lì, e si può controllare la variabile quando il run () è fatto.

Modifica per aggiungere: Scusa, volevo dire di farne una serie finale di una sola eccezione. Idea fa automaticamente per me, così spesso dimenticare il reindirizzamento in più.

final Exception[] except;

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top