在Java中,堆疊跟蹤是在構建例外時產生的,而不是在拋出例外時產生。有誰知道這種設計背后的原因是什么?
例如,在下面的程式中,我們在方法test1中拋出了一個例外,但是我們在另一個方法中實體化了這個例外,并且從main中呼叫了test1。結果,test1從未出現在堆疊跟蹤中:
class ExceptionNewVsThrow {
private static RuntimeException instantiateException() {
return new RuntimeException("Hello"/span>)。
}
private static void test1(Exception exception) throws Exception {
拋出例外。
}
public static void main(String[] args) throws Exception {
Exception exception = instantiateException()。
test1(exception)。
}
}
執行緒"main"java.lang.RuntimeException中出現例外。例外
在FSystem.experimental.exceptionNewVsThrow.instantiateException(ExceptionNewVsThrow.java:18)
at FSystem.experimental.exceptionNewVsThrow.main(ExceptionNewVsThrow.java:26)
。
uj5u.com熱心網友回復:
這就是throws陳述句的Java語言規范。 https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.18
而且看起來throws陳述句只是簡單地拋出例外;它并沒有建立進入例外的堆疊跟蹤。 根據設定例外的方法(Throwable類),看起來Java讓開發者負責構建例外,初始化它的原因和堆疊跟蹤,等等。因此,如果這是拋出的一部分,開發者就不會有同樣的靈活性。
因此,問題的答案是:將堆疊跟蹤作為例外構建的一部分來構建,會更加強大和靈活。
uj5u.com熱心網友回復:
在Java中,堆疊跟蹤是在構建例外時產生的,而不是在拋出時產生。 有誰知道這種設計背后的原因是什么嗎?
我不認為我們可以給你完整的(原始的)推理,因為這些決定很可能是在Java被稱為Oak(!)的時候做出的
。但有幾個優點是:
- 當你重新拋出一個例外時,原始的堆疊跟蹤被保留下來。 因此,例如,你可以在一個執行緒上捕獲一個例外,將其傳遞給另一個執行緒并重新拋出......并保留原來的堆疊跟蹤。
- 你可以在自定義例外的實作中做一些事情來改變創建堆疊跟蹤的方式;例如,你可以完全抑制它。 或者你可以對堆疊跟蹤進行 "按摩",以便向你的客戶隱藏秘密的內部細節。
- 捕獲堆疊跟蹤是昂貴的。 因此,如果
throw陳述句捕獲了它,就沒有任何機會來節省捕獲它的費用。 (無可否認,現代 JVM 有另一種方法來處理這個問題......但我們在這里討論的是原始設計決策。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/320019.html
標籤:
上一篇:將串列中的最后一個值除以前一個值
