BigDecimal.ZERO 與 new BigDecimal(0)
1. 概述
當我們使用BigDecimal,
使用BigDecimal
表示數值零是一項常見任務。但是,我們經常面臨兩種類似方法之間的選擇:使用BigDecimal.ZERO
或使用建構子new BigDecimal(0)
來建立新的BigDecimal
物件。
在本教程中,我們將探討這兩種方法之間微妙但顯著的區別,並討論何時選擇其中一種。
另外,為了簡單起見,我們將使用單元測試斷言來驗證結果。
2. 比較BigDecimal
對象
在比較BigDecimal.ZERO
和new BigDecimal(0),
讓我們先快速了解如何比較兩個BigDecimal
物件。
鑑於BigDecimal
類別實作了Comparable
接口,它為我們提供了使用equals()
方法或compareTo()
方法來比較兩個BigDecimal
的靈活性。然而,認識到這兩種方法在兩個BigDecimal
實例之間進行不同的比較至關重要。
假設我們有兩個BigDecimal
對象, bd1
和bd2.
如果bd1.compareTo(bd2) == 0,
則僅表示兩個BigDecimal
的值相等。例如, BigDecimal 42.00
和42.0000
的值相等,但小數位數不同:
BigDecimal bd1 = new BigDecimal("42.00");
BigDecimal bd2 = new BigDecimal("42.0000");
assertEquals(0, bd1.compareTo(bd2));
然而,值得注意的是**BigDecimal
中的equals()
方法根據 value 和 scale 來評估相等性**。因此,使用equals()
方法比較BigDecimal
42.00
與42.0000
將導致它們被視為不相等:
BigDecimal bd1 = new BigDecimal("42.00");
BigDecimal bd2 = new BigDecimal("42.0000");
assertNotEquals(bd1, bd2);
那麼,接下來,讓我們使用equals()
方法來比較BigDecimal.ZERO
和new BigDecimal(0)
:
BigDecimal zero = BigDecimal.ZERO;
BigDecimal zero0 = new BigDecimal(0);
assertEquals(zero, zero0);
正如上面的測試所證明的, BigDecimal.ZERO
和new BigDecimal(0)
在值和範圍上表現出相等。因此,它們在數學上是相同的。實際上,這意味著在計算中使用它們時沒有明顯的差異。
接下來我們來看看這兩個物件是如何實例化的。
3. BigDecimal.ZERO
內部如何運作?
BigDecimal.ZERO
是BigDecimal
類別中的常數欄位:
public static final BigDecimal ZERO = ZERO_THROUGH_TEN[0];
正如我們所看到的,它從名為ZERO_THROUGH_TEN:
private static final BigDecimal[] ZERO_THROUGH_TEN = {
new BigDecimal(BigInteger.ZERO, 0, 0, 1),
new BigDecimal(BigInteger.ONE, 1, 0, 1),
new BigDecimal(BigInteger.TWO, 2, 0, 1),
...
new BigDecimal(BigInteger.TEN, 10, 0, 2),
};
BigDecimal
預先實例化了 11 個物件( 0
到10
)。因此, BigDecimal.ZERO
和陣列中的其他實例可以隨時使用,無需建立額外的物件。
因此,每當我們使用BigDecimal.ZERO
時,我們都會引用同一個物件:
BigDecimal z1 = BigDecimal.ZERO;
BigDecimal z2 = BigDecimal.ZERO;
assertSame(z1, z2);
4. new BigDecimal(0)
內部如何運作?
另一方面, new BigDecimal(0) 透過指定值0
new BigDecimal(0)
建構函式建立一個新的BigDecimal
物件:
public BigDecimal(int val) {
this.intCompact = val;
this.scale = 0;
this.intVal = null;
}
當它呼叫建構函式時,每次我們呼叫new BigDecimal(0),
都會建立一個新物件:
BigDecimal z1 = new BigDecimal(0);
BigDecimal z2 = new BigDecimal(0);
assertNotSame(z1, z2);
5. 我們應該採取哪一種方法?
BigDecimal.ZERO
和new BigDecimal(0)
方法都創建不可變的BigDecimal
對象,確保線程安全性和一致性。然而,正如我們之前討論的, BigDecimal.ZERO
具有重用共享常數物件的額外優勢。當BigDecimal.ZERO
在程式庫的多個部分中使用時,將使用相同的物件引用,從而避免不必要的物件建立。
此外,在BigDecimal.ZERO
和new BigDecimal(0)
之間進行選擇時的主要考慮因素之一是程式碼傳達的清晰度和意圖。 BigDecimal.ZERO
因其可讀性和簡潔性而受到廣泛青睞。其不言自明的性質使程式碼更具表現力,並且符合表示 0 的明確意圖。
因此,當我們的目的是讓BigDecimal
物件表示值 0 時,建議選擇BigDecimal.ZERO
。
六,結論
在本文中,我們首先了解了BigDecimal.ZERO
和new BigDecimal(0)
方法如何實例化BigDecimal
實例。然後,我們從可讀性和物件重用的角度討論了應該採取哪種方法。
BigDecimal.ZERO
因其簡潔的語法、清晰的意圖和共享物件引用的潛力而脫穎而出。因此,如果我們想要一個BigDecimal
物件來表示值 0,那麼BigDecimal.ZERO
方法應該是我們的首選。
與往常一樣,範例的完整原始程式碼可在 GitHub 上取得。