簡體   English   中英

為什么Java在Exception / Throwable類中沒有setMessage?

[英]Why doesn't Java have setMessage in Exception/Throwable classes?

我無法理解為什么Java一旦創建就不允許更改Exception類型異常(或其超類Throwable)的異常消息。 它允許使用setStackTrace更改stackTrace,但不允許更改消息。

我用過的用例對我來說似乎是真實的,並會欣賞一些替代方案。

用例

我有一個控制器服務X,調用讓我們說10個其他依賴服務。 為了簡化調試,如果依賴服務拋出一些異常,我們希望從服務X向其上游顯示一些標識符,以便輕松識別失敗的請求。 為此我們有requestId,我們為每個依賴項創建和設置。

現在為了避免所有相關服務的重復並簡化代碼,我們可以創建一個通用攔截器,允許我們在每次調用之前和之后做一些工作。 就像是 -

// do some work

requestId = getRequestId(); // create or somehow get requestId
dependentService.setRequestId(requestId);

try {
  dependentService.call();
}
catch (Exception e) {
  e.setMessage(e.getMessage() + ... + requestId);
  throw e;
}

//do some work

但Java不允許我們設置消息。 同時,我們希望保留異常及其類型(可以是依賴服務定義的任何自定義類型),因此我不想執行諸如throw new Exception(e.getMessage() + ...)

算不上什么它的意思為,但你可以附加其他異常,並addSuppressed

} catch (Exception e) {
  e.addSuppressed(new ExtraInfoException(...));
  throw e;
}

where ...包含您要包含的額外信息。

相對於添加異常消息,這樣做的好處是,您可以定義ExtraInfoException ,使其在字段中具有您想要的信息,而不必將其從異常消息中解析出來。

話雖如此,附加更多異常信息的更慣用的方法是:

} catch (Exception e) {
  throw new ExtraInfoException(e, ...);
}

它具有允許您返回結構化信息的完全相同的優點,另外的優點是您可以直接捕獲ExtraInfoException ,而不是捕獲Exception ,然后反復尋找額外的信息。

為什么Java在Exception / Throwable類中沒有setMessage?

您的問題的答案是他們(圖書館設計師)並不認為更改異常消息是一件有用的事情。

在很大程度上1,設計師們所持的看法,他們不應該設計API直接支持所有可能的使用情況......包括晦澀那些幾乎沒有人會遇到。 喜歡你的2

在你的情況下,還有其他方法來實現你想要做的事情; 看到其他答案。

我快速搜索了Java錯誤數據庫,看看是否有其他人放入了一個RFE來為ThrowableException請求一個setMessage方法。 我找不到任何東西。 如果你的要求甚至有點普遍,那么可能會有一個RFE,解釋為什么它被拒絕了。


1 - 顯然,這有例外,但這不是重點。

2 - 顯然你會不同意你的用例是模糊的,但這也是不重要的。 問題是為什么他們沒有實現這一點,而不是他們是否錯了。 (詢問/辯論他們是否錯了是偏離主題的,因為這是一個意見問題。)

重置消息它是某種重寫歷史記錄。 當你捕獲異常並處理它們時,你有一個catch塊。 如果你需要在處理過程中拋出異常,那就是一個不同的問題,異常應該是不同的。

} catch (SomeException e) {
 // here we have SomeException and we want to handle it.
 // if we can't we throw a new one, because we have a problem with handling.
 // if the handling problem cause is SomeException we put it at the cause.
 throw new AnotherException("with some message", e);
}

在堆棧跟蹤中,我們將看到由於SomeException我們有AnotherException ,它為我們提供了有關問題根源的信息。

只需簡單地拋出這樣的新實例:

try {
...
} catch(Exception ex) {
   throw new Exception ("new message", ex);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM