Почему я получил сообщение о том, что ни одно исключение не выброшено?
У меня есть это в классе, который реализует Callable:
public class MasterCrawler implements Callable {
public Object call() throws SQLException {
resumeCrawling();
return true;
}
//more code with methods that throws an SQLException
}
В другом классе, который выполняет этот Callable, что-то вроде этого:
MasterCrawler crawler = new MasterCrawler();
try{
executorService.submit(crawler); //crawler is the class that implements Callable
}(catch SQLException){
//do something here
}
Но я получил ошибку и сообщение IDE, что SQLException никогда не выбрасывается. Это потому, что я выполняю в ExecutorService?
ОБНОВЛЕНИЕ: Таким образом, отправка не выдает исключение SQLException. Как я могу сделать, чтобы выполнить Callable (запустить как поток) и поймать исключение?
РЕШИТЬ:
public class MasterCrawler implements Callable {
@Override
public Object call() throws Exception {
try {
resumeCrawling();
return true;
} catch (SQLException sqle) {
return sqle;
}
}
}
Future resC = es.submit(masterCrawler);
if (resC.get(5, TimeUnit.SECONDS) instanceof SQLException) {
//do something here
}
4 ответа
Когда вы звоните submit
Вы передаете объект. Ты не звонишь call()
,
РЕДАКТИРОВАТЬ
Submit
возвращает будущее f. Когда вы звоните f.get()
метод может вызвать исключение ExecutionException, если во время выполнения вызываемого объекта возникла проблема. Если это так, он будет содержать исключение, выданное call()
,
Отправляя свой Callable исполнителю, вы фактически просите его выполнить его (асинхронно). Нет необходимости в дальнейших действиях. Просто верни будущее и жди.
О РЕШЕНИИ
Хотя ваше решение будет работать, это не очень чистый код, потому что вы перехватываете возвращаемое значение Call. Попробуйте что-то вроде этого:
public class MasterCrawler implements Callable<Void> {
@Override
public Void call() throws SQLException {
resumeCrawling();
return null;
}
public void resumeCrawling() throws SQLException {
// ... if there is a problem
throw new SQLException();
}
}
public void doIt() {
ExecutorService es = Executors.newCachedThreadPool();
Future<Void> resC = es.submit(new MasterCrawler());
try {
resC.get(5, TimeUnit.SECONDS);
// Success
} catch ( ExecutionException ex ) {
SQLException se = (SQLException) ex.getCause();
// Do something with the exception
} catch ( TimeoutException ex ) {
// Execution timed-out
} catch ( InterruptedException ex ) {
// Execution was interrupted
}
}
Какой IDE вы используете? Когда я пробую ваш код, Eclipse жалуется на "необработанное исключение типа исключения". Это имеет смысл, потому что Callable
Интерфейс определяет call()
метод бросить Exception
, Только потому, что ваш класс реализации объявляет более ограниченный тип исключения, вызывающая программа не может рассчитывать на это. Он ожидает, что вы поймаете исключение.
Это потому, что SQLException никогда не будет сгенерирован сканером.
Попробуй использовать finally
вместо catch
и посмотрим, возникнет ли у вас проблема или она сработает.