[英]Why does Throwable.getCause check to see if 'cause' is 'this' before returning `null` instead of just returning the cause directly?
今天我有理由進入Throwable.getCause
的源代碼,並且在該方法中看到此代碼時有點驚訝:
public synchronized Throwable getCause() {
return (cause==this ? null : cause);
}
這是來自 Java 1.8,但在我看過的更高版本中看起來相同。
我的問題是:為什么不簡單地return cause
並完成它?
它不是將cause
與null
進行比較,而是將cause
與this
進行比較。 為避免循環,如果cause
是this
,則返回 null。
編碼:
public synchronized Throwable getCause() {
return (cause==this ? null : cause);
}
說如果cause
是this
返回null
否則返回cause
(它也可能是null
因為它發生。
故事是這樣開始的: private Throwable cause = this;
我相信所有版本>=1.4 都是一樣的。 這將原因初始化為這個對象!
目的是Throwable
對象是不可變的,但它提供了一個方法void initCause(Throwable cause)
只能調用一次來初始化原因或由構造函數初始化的原因。
正如文檔所解釋的那樣,允許將原因鏈接到在引入cause
之前添加的子類,這些子類不包含在其構造函數之一中。
因此,該類以某種方式想知道是否已調用initCause
並拋出IllegalStateException
如果有)(我的評論):
public Throwable initCause(Throwable cause) {
if (cause == this) //Illogical! An exception can't be self caused!
throw new IllegalArgumentException();
if (this.cause != this)// false if cause has been initialised 'properly'.
throw new IllegalStateException();
this.cause = cause;
return this;
}
該類使用cause==this
來指示未設置cause
。 它不能使用cause==null
因為null
是一個有效值。 所以它使用了cause==this
的異常狀態,因為主動設置cause
到this
是自引發異常的不合邏輯狀態。
它確實有效。 但這真的是個好主意嗎? 我說不是。 它將“原因未設置”和“原因已設置並設置為null
”的狀態混為一談。 一個不太扭曲的設計只是引入了一個標志private boolean isCauseSet=false;
並在initCause
被調用或設置它的構造函數被調用時設置它。
我們在Throwable
看到的復雜代碼只不過是避免了boolean
。 在Throwable
保存單個boolean
字段似乎真的不值得打擾。 沒有任何有用的應用程序會在流通中擁有如此多的Throwable
對象,因此它很重要。
該null
值由printStackTrace
方法使用, 例如,在調用stackTraceString
方法時,第 421..450行標識堆棧跟蹤的輸出應何時完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.