У меня есть метод, который выполняет какую-то задачу с тайм-аутом. Я использую ExecutorServer.submit ()для получения объекта Future, а затем вызываю future.get ()с тайм-аутом. Это работает нормально, но мой вопрос - лучший способ обработки проверенных исключений, которые могут быть вызваны моей задачей. Следующий код работает и сохраняет проверенные исключения, но он кажется чрезвычайно неуклюжим и подвержен поломке, если список проверенных исключений в сигнатуре метода изменится.
Есть предложения, как это исправить? Мне нужно ориентироваться на Java 5, но мне также было бы любопытно узнать, есть ли хорошие решения в более новых версиях Java.
public static byte[] doSomethingWithTimeout( int timeout ) throws ProcessExecutionException, InterruptedException, IOException, TimeoutException {
Callable<byte[]> callable = new Callable<byte[]>() {
public byte[] call() throws IOException, InterruptedException, ProcessExecutionException {
//Do some work that could throw one of these exceptions
return null;
}
};
try {
ExecutorService service = Executors.newSingleThreadExecutor();
try {
Future<byte[]> future = service.submit( callable );
return future.get( timeout, TimeUnit.MILLISECONDS );
} finally {
service.shutdown();
}
} catch( Throwable t ) { //Exception handling of nested exceptions is painfully clumsy in Java
if( t instanceof ExecutionException ) {
t = t.getCause();
}
if( t instanceof ProcessExecutionException ) {
throw (ProcessExecutionException)t;
} else if( t instanceof InterruptedException ) {
throw (InterruptedException)t;
} else if( t instanceof IOException ) {
throw (IOException)t;
} else if( t instanceof TimeoutException ) {
throw (TimeoutException)t;
} else if( t instanceof Error ) {
throw (Error)t;
} else if( t instanceof RuntimeException) {
throw (RuntimeException)t;
} else {
throw new RuntimeException( t );
}
}
}
=== UPDATE ===
Многие люди публиковали ответы, в которых рекомендовалось либо 1 )re -бросать как общее исключение, либо 2 )re -бросать как непроверенное исключение. Я не хочу делать ничего из этого, потому что эти типы исключений (ProcessExecutionException, InterruptedException, IOException,TimeoutException )важны -, каждое из них будет обрабатываться по-разному при обработке вызова. Если бы мне не нужна была функция тайм-аута, то я бы хотел, чтобы мой метод выдавал эти 4 конкретных типа исключений (ну, за исключением TimeoutException ). Я не думаю, что добавление функции тайм-аута должно изменить сигнатуру моего метода, чтобы генерировать общий тип исключения.