2011-05-27 60 views
1

我有這個在實現可調用的類:爲什麼我得到一個錯誤,說沒有人拋出異常?

public class MasterCrawler implements Callable { 
    public Object call() throws SQLException { 
     resumeCrawling(); 
     return true; 
    } 
    //more code with methods that throws an SQLException 
} 

在這種執行該贖回,像這樣其他類:

MasterCrawler crawler = new MasterCrawler(); 
try{ 
    executorService.submit(crawler); //crawler is the class that implements Callable 
}(catch SQLException){ 
    //do something here 
} 

但我得到了一個錯誤和IDE的消息SQLException永遠不會拋出。這是因爲我在ExecutorService中執行?

UPDATE:所以提交不會拋出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 
} 
+0

Callable引發異常。 http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html – 2011-05-27 02:34:32

回答

2

當您致電submit時,您正在傳遞一個對象。你不叫call()

EDIT

Submit返回Future F。當您致電f.get()時,如果在執行可調用期間遇到問題,該方法可能會觸發ExecutionException。如果是這樣,它將包含call()拋出的異常。

通過將您的Callable提交給執行者,實際上是要求它執行它(異步)。無需採取進一步行動。只要找回未來並等待。

有關解決方案

雖然你的解決方案將工作,這不是很乾淨的代碼,因爲你劫持調用的返回值。試試這樣的:

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 

    } 

} 
+0

如何獲取調用方法拋出的異常? – 2011-05-27 02:09:14

+1

@ditkin不,這不是正確的方法,因爲如果你想通知調用者/調用者,捕獲調用中的異常不會告訴你如何將它傳遞給調用者/調用者。你需要讓未來抓住它。 – JVerstry 2011-05-27 02:22:06

+0

我在呼叫方法內引發異常並將其返回,並對IF產生威脅。看起來有點奇怪,我會找到另一種方式,但現在,解決我的問題。 – 2011-05-27 03:00:45

1

的提交方法不拋出SQLException。

0

這是因爲SQLException永遠不會被抓取工具拋出。

嘗試使用finally而不是catch,看看你是否會遇到問題或工作。

+0

不,這根本無濟於事......而且,如果沒有首先抓住。 – JVerstry 2011-05-27 02:20:08

+0

等等...我可以,我經常這樣做。如果您不希望在此步驟的代碼中使用捕獲異常,但可以在更全局的範圍內執行此操作。 – 2011-05-27 02:26:42

0

你在用什麼IDE?當我嘗試你的代碼時,Eclipse會抱怨「未處理的異常類型異常」。這很有意義,因爲Callable接口定義了call()方法來拋出Exception。僅僅因爲你的實現類聲明瞭一個更受限制的異常類型,調用程序就不能指望它。它期望你能抓住異常。

相關問題