Boolean.TRUE和true之间有什么区别

时间:2015-08-02 19:14:22

标签: java wrapper

首先,我有

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;

我想我还是不能很好地理解包装类。请给我一些指导。谢谢!

4 个答案:

答案 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。由于Booleanfalse对象,因此比较是在两个引用之间(并且将始终返回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)

如果字典不包含swordDict.contains(s)false),则会评估第二个条件(mem.get(s) == true)。

在Java的库Maps中,尝试获取不存在的键的值会返回null。因此,每次该密钥不在mem地图中时,都会返回null,并与==进行比较(使用true)。当Boolean类型与boolean值进行比较或分配时,它为'autounboxed'。这意味着调用了Boolean.booleanValue()方法。如果Booleannull,则会导致异常,因为这意味着调用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之类的内容。第一次检查确保没有空引用。