[英]What the difference between Boolean.TRUE and true
首先,我有
private Map<String, Boolean> mem = new HashMap<String, Boolean>();
接着:
if (wordDict.contains(s) || Boolean.TRUE==mem.get(s)) {
return true;
}
為什么我不能在if語句中使用“mem.get(s)== true”。 將出現錯誤“第6行:java.lang.NullPointerException”
我想我還是不能很好地理解包裝類。 請給我一些指導。 謝謝!
如果mem.get(s)
為null並將與原始布爾值進行比較,則java將進行自動裝箱。 這意味着它將調用null.booleanValue()
。
這就是你獲得NPE的原因。
這比基於語言的問題更具邏輯性。 if(mem.contains(s) || Boolean.TRUE == mem.get(s))
將只檢查條件的第二部分,如果s
不在mem
。 因此,比較等效於Boolean.TRUE == null
。 由於Boolean.TRUE
是一個Boolean
對象,因此比較是在兩個引用之間(並且總是返回false
)。 另一方面, boolean
是一種原始類型,因此必須首先轉換從mem
檢索的Boolean
。 由於它為null
,因此無法轉換為基本類型。
看起來mem.get(s)
返回Boolean
類型的結果。 在java中,有兩種類型用於處理邏輯值。 Boolean
對象類型和boolean
元類型。
為了評估if
語句的邏輯表達式,java 使用autoboxing將Boolean
轉換為boolean
。
但是,如果您的方法返回null
而不是Boolean
對象,則java無法將此值取消裝箱為布爾基元類型。 而且你得到NullPointerException。
只要字典不包含s
( wordDict.contains(s)
為false
),就會計算第二個條件( mem.get(s) == true
)。
在Java的庫Maps中,嘗試獲取不存在的鍵的值將返回null
。 因此,每次該密鑰不在mem
map中時,返回null
,並將(使用==
)與true
。 當Boolean
類型獲取與相比,或分配給,一個boolean
值,它是“autounboxed” 。 這意味着調用了Boolean.booleanValue()
方法。 如果Boolean
為null
,則這是導致異常的原因,因為它意味着調用null.booleanValue()
。 null
不是任何東西,因此它不知道如何成為布爾值!
包裝類是有用的結構,它使原始類型能夠與繼承自Object
類型(即引用類型(其他所有內容))進行互操作。 當你處理原始類型('value'類型)時,它們的值直接出現在它們所描述的位置 - 作為用於執行當前函數的內存的一部分(用於局部變量)或作為一部分分配給其內存空間中對象的內存空間(用於字段變量)。 當您處理引用類型(繼承自Object
,包括Boolean
和其他包裝類型)時,引用的數據將存在於名為Heap的內存空間中。 除了這個堆內存分配,為了知道該對象的位置,類似於值類型的值的實體實際上是對象的內存位置的引用 ,存儲為局部變量或字段變量, 而不是值或對象本身的數據 。 這使得這些變為null
: null
引用表示此變量沒有特別指向任何內容。 (有關更多詳細信息,請參閱堆棧和堆分配。)
與Boolean.TRUE
比較安全的原因是因為在Object
類型上,比如Boolean
(以及基本類型的任何包裝類), Boolean
類型的變量實際上是一個引用。 這意味着==
運算符實際上是在檢查引用是否相同 - 即內存中的實際對象是否相同(具有相同的內存位置),而不是它們是否與某些基於值的定義“相等”等於'。 你不希望這樣,因為你可以獲得令人驚訝的結果,比如new Boolean(true) == new Boolean(true)
返回false。 這就是為什么我們有equals
方法 - 這應該由任何類來定義一個想要通過值而不是通過引用進行比較的對象。 另一方面,對於原始值類型,如boolean
, ==
運算符字面上比較該值。 這就是為什么自動包裝類型框和unbox是有用的 - 一個Boolean
變量(沒有被'取消引用' - 找到它指向的值)實際上是一個引用值,指的是一個內存位置。 boolean
變量是實際的布爾值。 因此,如果沒有自動拆箱和裝箱,嘗試比較兩者是沒有意義的。
如果要確保mem.get(s)
值既不是null
也不是false
,請使用mem.containsKey(s) && mem.get(s) == true
。 第一次檢查確保沒有空引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.