我會先用我的用例迅速激發這個問題。 我的庫需要將Java異常分類器公開給它插入的框架。例如:鏈式異常的循環
enum Classification { FATAL, TRANSIENT, UNKNOWN }
Classification classify(Throwable t) {
if (t instanceof MyTransientException)
return Classification.TRANSIENT;
else if (t instanceof MyFatalException)
return Classification.FATAL;
else
return Classification.UNKNOWN;
}
有時候,和原因在我的掌握,傳遞的例外是圍繞着一個我很感興趣,所以我想搜索的連鎖事業爲它的包裝。我最初的想法是:
Classification classify(Throwable t) {
if (t == null)
return Classification.UNKNOWN;
if (t instanceof MyTransientException)
return Classification.TRANSIENT;
else if (t instanceof MyFatalException)
return Classification.FATAL;
else
return classify(t.getCause());
}
不幸的是,這可能會導致無窮遞歸如果傳遞的例外在其因果鏈的循環。這樣的例外很可能不會被傳遞,並且如果創建了這樣一個例外,那麼可以認爲這是系統中其他地方的錯誤,但是我對我的庫負責生產的可能性感到非常不舒服發生中斷。 Throwable的API和javadoc並沒有明確禁止這種可能性,除了循環在因果鏈中本身無意義的想法。
我注意到,番石榴有一個@Beta方法來提取因果鏈,Throwables.getCausalChain,但它的實現容易出現同樣的問題 - 它會結束投擲OOME。
我打算使用identity hash set來檢測週期並降低風險,但我想聽聽其他人如何看待此問題。你認爲我過於防守嗎?你會怎麼做?