Boolean.TRUE 和 true 有什么区别
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"。会出现错误"Line 6: java.lang.NullPointerException"
我想我还是不能很好地理解 wrapper class。请给我一些指导。谢谢!
如果 mem.get(s)
为 null 并将与原始布尔值进行比较,java 将进行自动装箱。这意味着它将调用 null.booleanValue()
.
这就是你获得 NPE 的原因。
这更像是一个逻辑问题,而不是基于语言的问题。如果 s
不在 mem
中,if(mem.contains(s) || Boolean.TRUE == mem.get(s))
将只检查条件的第二部分。因此比较等同于 Boolean.TRUE == null
。由于 Boolean.TRUE
是一个 Boolean
对象,比较是在两个引用之间进行的(并且总是 return false
)。另一方面,boolean
是原始类型,因此必须首先转换从 mem
检索到的 Boolean
。由于它是 null
,因此无法转换为原始类型。
看起来是 mem.get(s)
returns Boolean
类型的结果。在 java 中有两种处理逻辑值的类型。 Boolean
对象类型和 boolean
原始类型。
为了计算 if
语句的逻辑表达式,java 将 Boolean
转换为 boolean
using autoboxing。
但是如果您的方法 returns null
而不是 Boolean
对象,则 java 无法将此值拆箱为布尔原始类型。然后你得到 NullPointerException。
只要字典不包含 s
(wordDict.contains(s)
是 false
),就会计算第二个条件 (mem.get(s) == true
)。
在 Java 的地图库中,试图获取不存在的键的值 returns null
。因此,每次该键不在 mem
映射中时,都会返回 null
,并与 true
进行比较(使用 ==
)。当 Boolean
类型与 boolean
值进行比较或赋值时,它是 'autounboxed'。这意味着 Boolean.booleanValue()
方法被调用。如果 Boolean
是 null
,这就是导致异常的原因,因为它意味着调用 null.booleanValue()
。 null
什么都不是,所以它不知道如何成为布尔值!
包装器 classes 是有用的构造,它使基本类型能够与继承自 Object
的类型进行互操作,即引用类型(其他所有内容)。当您处理基本类型('value' 类型)时,它们的值直接存在于它们被描述的位置 - 作为用于执行当前函数(对于局部变量)的内存的一部分或作为一部分内存 space 分配给 its 内存 space 中的对象(用于字段变量)。当您处理引用类型(那些继承自 Object
,包括 Boolean
和其他包装类型)时,被引用的数据反而存在于称为 [=47= 的内存 space 中].除了这个堆内存分配,为了知道那个对象在哪里,类似于值类型的值的实体实际上是一个对对象内存位置的引用,存储为局部变量或字段变量,不是对象本身的值或数据。这就是使它们成为 null
的原因:null
引用表明该变量没有特别指向任何内容。 (阅读有关堆栈和堆分配的更多详细信息。)
与 Boolean.TRUE
比较安全的原因是因为在 Object
类型上,例如 Boolean
(以及任何原始类型的包装器 classes) , Boolean
类型的变量实际上是一个引用。这意味着 ==
运算符实际上正在检查 if the references are the same - 即内存中的实际对象是否相同(具有相同的内存位置),而不是它们是否 'equal' 某个值 -基于 'equal' 的定义。您不希望这样,因为您可能会得到令人惊讶的结果,例如 new Boolean(true) == new Boolean(true)
返回 false。顺便说一句,这就是我们使用 equals
方法的原因 - 这应该由任何 class 定义,用于希望按值而不是按引用进行比较的对象。另一方面,对于原始值类型,如 boolean
,==
运算符按字面意思比较值。这就是为什么让包装器类型自动装箱和拆箱很有用 - Boolean
变量(不是 'dereferenced' - 找到它指向的值)实际上是一个参考值,指的是内存位置。 boolean
变量是一个实际的布尔值。因此,如果没有自动拆箱和装箱,尝试比较两者是没有意义的。
如果您想确保 mem.get(s)
的值既不是 null
,也不是 false
,请使用类似 mem.containsKey(s) && mem.get(s) == 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"。会出现错误"Line 6: java.lang.NullPointerException"
我想我还是不能很好地理解 wrapper class。请给我一些指导。谢谢!
如果 mem.get(s)
为 null 并将与原始布尔值进行比较,java 将进行自动装箱。这意味着它将调用 null.booleanValue()
.
这就是你获得 NPE 的原因。
这更像是一个逻辑问题,而不是基于语言的问题。如果 s
不在 mem
中,if(mem.contains(s) || Boolean.TRUE == mem.get(s))
将只检查条件的第二部分。因此比较等同于 Boolean.TRUE == null
。由于 Boolean.TRUE
是一个 Boolean
对象,比较是在两个引用之间进行的(并且总是 return false
)。另一方面,boolean
是原始类型,因此必须首先转换从 mem
检索到的 Boolean
。由于它是 null
,因此无法转换为原始类型。
看起来是 mem.get(s)
returns Boolean
类型的结果。在 java 中有两种处理逻辑值的类型。 Boolean
对象类型和 boolean
原始类型。
为了计算 if
语句的逻辑表达式,java 将 Boolean
转换为 boolean
using autoboxing。
但是如果您的方法 returns null
而不是 Boolean
对象,则 java 无法将此值拆箱为布尔原始类型。然后你得到 NullPointerException。
只要字典不包含 s
(wordDict.contains(s)
是 false
),就会计算第二个条件 (mem.get(s) == true
)。
在 Java 的地图库中,试图获取不存在的键的值 returns null
。因此,每次该键不在 mem
映射中时,都会返回 null
,并与 true
进行比较(使用 ==
)。当 Boolean
类型与 boolean
值进行比较或赋值时,它是 'autounboxed'。这意味着 Boolean.booleanValue()
方法被调用。如果 Boolean
是 null
,这就是导致异常的原因,因为它意味着调用 null.booleanValue()
。 null
什么都不是,所以它不知道如何成为布尔值!
包装器 classes 是有用的构造,它使基本类型能够与继承自 Object
的类型进行互操作,即引用类型(其他所有内容)。当您处理基本类型('value' 类型)时,它们的值直接存在于它们被描述的位置 - 作为用于执行当前函数(对于局部变量)的内存的一部分或作为一部分内存 space 分配给 its 内存 space 中的对象(用于字段变量)。当您处理引用类型(那些继承自 Object
,包括 Boolean
和其他包装类型)时,被引用的数据反而存在于称为 [=47= 的内存 space 中].除了这个堆内存分配,为了知道那个对象在哪里,类似于值类型的值的实体实际上是一个对对象内存位置的引用,存储为局部变量或字段变量,不是对象本身的值或数据。这就是使它们成为 null
的原因:null
引用表明该变量没有特别指向任何内容。 (阅读有关堆栈和堆分配的更多详细信息。)
与 Boolean.TRUE
比较安全的原因是因为在 Object
类型上,例如 Boolean
(以及任何原始类型的包装器 classes) , Boolean
类型的变量实际上是一个引用。这意味着 ==
运算符实际上正在检查 if the references are the same - 即内存中的实际对象是否相同(具有相同的内存位置),而不是它们是否 'equal' 某个值 -基于 'equal' 的定义。您不希望这样,因为您可能会得到令人惊讶的结果,例如 new Boolean(true) == new Boolean(true)
返回 false。顺便说一句,这就是我们使用 equals
方法的原因 - 这应该由任何 class 定义,用于希望按值而不是按引用进行比较的对象。另一方面,对于原始值类型,如 boolean
,==
运算符按字面意思比较值。这就是为什么让包装器类型自动装箱和拆箱很有用 - Boolean
变量(不是 'dereferenced' - 找到它指向的值)实际上是一个参考值,指的是内存位置。 boolean
变量是一个实际的布尔值。因此,如果没有自动拆箱和装箱,尝试比较两者是没有意义的。
如果您想确保 mem.get(s)
的值既不是 null
,也不是 false
,请使用类似 mem.containsKey(s) && mem.get(s) == true
的值。第一次检查确保不会有空引用。