首先,我有
private Map<String, Boolean> mem = new HashMap<String, Boolean>();
然后:
if (wordDict.contains(s) || Boolean.TRUE==mem.get(s)) {
return true;
}
为什么我不能使用&#34; mem.get(s)== true&#34;在if语句中。将出现错误&#34;第6行:java.lang.NullPointerException&#34;
我想我还是不能很好地理解包装类。请给我一些指导。谢谢!
答案 0 :(得分:5)
如果mem.get(s)
为null并且将与原始布尔值进行比较,则java将进行自动装箱。这意味着它将调用null.booleanValue()
。
这就是你获得NPE的原因。
答案 1 :(得分:2)
这比基于语言的问题更具逻辑性。如果if(mem.contains(s) || Boolean.TRUE == mem.get(s))
中s
不在mem
,则Boolean.TRUE == null
只会检查条件的第二部分。因此,比较等同于Boolean.TRUE
。由于Boolean
是false
对象,因此比较是在两个引用之间(并且将始终返回boolean
)。另一方面,Boolean
是原始类型,因此必须首先转换从mem
检索的null
。由于它是<?php
session_start();
if($_SESSION['user']){
}
else{
header("location:index.php");
}
if($_SERVER['REQUEST_METHOD'] = "POST") //Added an if to keep the page secured
{
$author=$_SESSION['user'];// here you are getting the author . as the person who is logged will add a row to the list
$details = mysql_real_escape_string($_POST['details']);
$time = strftime("%X");//time
$date = strftime("%B %d, %Y");//date
$decision ="no";
mysql_connect("localhost", "root","") or die(mysql_error()); //Connect to server
mysql_select_db("first_db") or die("Cannot connect to database"); //Connect to database
foreach($_POST['public'] as $each_check) //gets the data from the checkbox
{
if($each_check !=null ){ //checks if the checkbox is checked
$decision = "yes"; //sets teh value
}
}
mysql_query("INSERT INTO list (details, date_posted, time_posted, public,author) VALUES ('$details','$date','$time','$decision','$author')"); //SQL query
header("location: home.php");
}
else
{
header("location:home.php"); //redirects back to hom
}
?>
,因此无法将其转换为基本类型。
答案 2 :(得分:2)
看起来mem.get(s)
返回Boolean
类型的结果。在java中,有两种类型用于处理逻辑值。 Boolean
对象类型和boolean
基元类型。
要评估if
语句的逻辑表达式,java会将Boolean
转换为boolean
using autoboxing。
但是如果你的方法返回null
而不是Boolean
对象,那么java无法将此值解包为布尔基元类型。你得到NullPointerException。
答案 3 :(得分:1)
如果字典不包含s
(wordDict.contains(s)
为false
),则会评估第二个条件(mem.get(s) == true
)。
在Java的库Maps中,尝试获取不存在的键的值会返回null
。因此,每次该密钥不在mem
地图中时,都会返回null
,并与==
进行比较(使用true
)。当Boolean
类型与boolean
值进行比较或分配时,它为'autounboxed'。这意味着调用了Boolean.booleanValue()
方法。如果Boolean
为null
,则会导致异常,因为这意味着调用null.booleanValue()
。 null
不是什么,所以它不知道如何成为布尔值!
包装类是有用的结构,它使原始类型能够与继承自Object
的类型(即引用类型(其他所有内容))进行互操作。当你处理原始类型('value'类型)时,它们的值直接出现在它们所描述的位置 - 作为用于执行当前函数的内存的一部分(用于局部变量)或作为一部分分配给其内存空间(对于字段变量)中的对象的内存空间。当您处理引用类型(继承自Object
的引用类型,包括Boolean
和其他包装类型)时,引用的数据将存在于名为Heap的内存空间中。除了这个堆内存分配,为了知道该对象的位置,与值类型的值类似的实体实际上是对象的内存位置的引用,存储为局部变量或字段变量,不是对象本身的值或数据。这就是使null
成为null
的原因:Boolean.TRUE
引用说这个变量没有特别指向。 (有关更多详细信息,请参阅堆栈和堆分配。)
与Object
比较安全的原因是因为在Boolean
类型上,如Boolean
(以及基本类型的任何包装类),类型为{==
的变量1}}实际上是一个参考。这意味着new Boolean(true) == new Boolean(true)
运算符实际上正在检查if the references are the same - 即内存中的实际对象是否相同(具有相同的内存位置),而不是它们是否与某些基于值的定义“相等” '平等'。您不希望这样,因为您可以获得令人惊讶的结果,例如equals
返回false。这就是为什么我们有boolean
方法的原因 - 这应该由任何类来定义一个想要通过值而不是通过引用进行比较的对象。另一方面,对于原始值类型,如==
,Boolean
运算符会逐字地比较该值。这就是为什么自动包装类型框和取消框是有用的 - boolean
变量(没有被'取消引用' - 找到它指向的值)实际上是一个引用值,指的是一个内存位置。 mem.get(s)
变量是实际的布尔值。因此,如果没有自动拆箱和装箱,尝试比较两者是没有意义的。
如果您想确保null
的值既不是false
,也不是mem.containsKey(s) && mem.get(s) == true
,请使用Time
之类的内容。第一次检查确保没有空引用。