什么时候应该使用布尔值的空值?

Java boolean允许truefalse值,而Boolean允许truefalsenull 。 我已经开始把我的boolean s转换为Boolean s。 这可能会导致testing中崩溃,如

 Boolean set = null; ... if (set) ... 

而testing

 if (set != null && set) ... 

似乎做作和容易出错。

什么时候用空值使用Boolean值是有用的? 如果从不,那么包装对象的主要优点是什么?

更新:有很多有价值的答案,我在自己的答案中总结了一些。 我最好是Java中的一个中间体,所以我试图展示我觉得有用的东西。 请注意,问题是“错误措词”(布尔不能“有一个空值”),但我已经离开它,以防其他人有相同的误解

每次可以使用boolean而不是Boolean 。 这将避免许多NullPointerException ,并使您的代码更健壮。

Boolean是有用的,例如

  • 在集合中存储布尔(列表,地图等)
  • 表示可空的布尔值(例如,来自数据库中的可为空的布尔列)。 在这种情况下,空值可能意味着“我们不知道它是真的还是假的”。
  • 每次一个方法需要一个Object作为参数,并且你需要传递一个布尔值。 例如,使用reflection或像MessageFormat.format()方法时。

我几乎从不使用Boolean因为它的语义是模糊和模糊的。 基本上你有三态逻辑:真,假或未知。 有时,当你给用户在两个值之间进行select时,使用它是有用的,并且用户根本没有回答,而且你确实想知道这些信息(想想:可以为NULLable的数据库列)。

我看不出有什么理由从boolean转换为boolean ,因为它引入了额外的内存开销,NPE的可能性和较less的input。 通常我使用笨拙的BooleanUtils.isTrue()使Boolean变得更容易一些。

Boolean存在的唯一原因是能够具有Booleantypes的集合(generics不允许boolean以及所有其他基元)。

哇,究竟是什么? 这只是我还是所有这些答案错误或至less误导?

布尔类是布尔基元types的包装。 这个包装器的使用是能够在一个接受对象或generics的方法中传递一个布尔值。 即vector。

一个布尔对象永远不能有null值。 如果您布尔值的引用为空,则表示您的布尔值从未创build。

你可能会觉得这很有用: http : //grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Boolean.java

一个null布尔引用只能用来触发你有任何其他空引用的类似的逻辑。 将它用于三个状态逻辑是笨拙的。

编辑:注意,那Boolean a = true; 是一个误导性的声明。 这实际上等于更接近于Boolean a = new Boolean(true); 请参阅自动装箱: http : //en.wikipedia.org/wiki/Boxing_%28computer_science%29#Autoboxing

也许这就是大部分困惑来自的地方。

编辑2:请阅读下面的评论。 如果任何人有一个如何重组我的答案,纳入这个想法,请这样做。

有三个简单的原因:

  • 表示数据库布尔值,可能是truefalsenull
  • xsd:nillable="true"表示XML模式的xsd:boolean
  • 能够使用genericstypes: List<Boolean> – 不能使用List<boolean>

回答自己的问题:我认为回答我自己的问题是有用的,因为我从答案中学到了很多东西。 这个答案是为了帮助像我这样的人,他们对问题没有完全的理解。 如果我使用不正确的语言,请纠正我。

  • 空“价值”不是一个价值,与false是根本不同的。 没有指向对象的指针。 所以认为布尔值是3值是根本错误的
  • 布尔的语法是缩写并隐藏的事实,参考指向对象:

    Boolean a = true;

隐瞒true是一个客体的事实。 其他等效的分配可能是:

 Boolean a = Boolean.TRUE; 

要么

 Boolean a = new Boolean(true); 
  • 缩写的语法

    if (a) ...

与大多数其他作业不同,隐藏了一个可能是一个对象引用或一个原语的事实。 如果一个对象需要testing为null以避免NPE。 对于我来说,如果存在平等testing,记住这一点在心理上更容易:

if (a == true) ...

我们可能会被提示testingnull。 所以缩短的forms只有在一个原始的时候才是安全的。

对于我自己,我现在有这样的build议:

  • 从不使用null作为3值逻辑。 只用真假。
  • 不要从方法返回Boolean ,因为它可能为null 。 只返回boolean
  • 只能使用Boolean来包装容器中的元素,或者需要对象的方法的参数

基元的包装类可以用在需要对象的地方,集合是一个很好的例子。

想象一下,由于某种原因,需要在ArrayList存储一个boolean序列,这可以通过boolean中的Boolean

这里有几句话

从文档:

正如任何Java程序员所知道的,你不能把一个int(或其他原始值)放到一个集合中。 集合只能保存对象引用,所以你必须将原始值装入适当的包装类(在整数情况下是整数)。 当你把对象从集合中取出时,你得到了你放入的Integer; 如果您需要int,则必须使用intValue方法取消Integer。 所有这些拳击和拆箱是一个痛苦,并混乱了你的代码。 自动装箱和取消装箱function可以自动执行此过程,消除疼痛和混乱。

http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

当你想要分配值还是不分开truefalse时, Boolean包装器很有用。 它有以下三种状态:

  • 真正
  • 没有定义哪个是null

boolean只有两个状态:

  • 真正

上述差异将会使它在Boolean值列表中有帮助, Boolean值可以是TrueFalseNull

我想在某些情况下,你应该有一个机制来区分已经设定值的布尔字段。

布尔值的主要用途是空值。 空值表示,该属性是未定义的 ,例如采取数据库可空列。

如果你真的需要从原始布尔值转换为包装布尔值,那么你可以使用以下来支持旧的代码:

 Boolean set = Boolean.FALSE; //set to default value primitive value (false) ... if (set) ... 

在布尔包装器中有** null **值的许多用法! 🙂

例如,您可能需要在表单中填写一个名为“newsletter”的字段,用于指示用户是否希望从您的网站获取简报。 如果用户没有在这个字段中select一个值,你可能想实现一个默认行为(发送?不发送?,再次提问?等)。 显然,没有设置(或没有select或**空**),是不一样的真或假。

但是,如果“未设置”不适用于您的模型,请不要更改布尔原语;)

在一个布尔元素的严格定义中,只有两个值。 在一个完美的世界里,那将是事实。 在现实世界中,元素可能缺失或未知。 通常,这涉及用户input。 在基于屏幕的系统中,可以通过编辑强制执行。 在使用数据库或XMLinput的批处理世界中,元素可能很容易丢失。

所以,在我们生活的非完美的世界里,布尔对象很好,它可以将缺失或未知的状态表示为空。 毕竟,计算机只是对现实世界进行build模,应该考虑所有可能的状态,并抛出exception来处理它们(主要是因为存在引发exception的用例是正确的响应)。

在我的情况下,布尔对象是一个完美的答案,因为inputXML有时缺less元素,我仍然可以得到一个值,将它赋值给布尔值,然后在尝试使用true或falsetesting之前检查null 。

只是我2美分。

对于上面的所有好的答案,我只要在Java servlet HttpSession类中给出一个具体的例子。 希望这个例子有助于澄清你可能仍然有的一些问题。

如果您需要存储和检索会话的值,请使用setAttribute (String,Object)和getAttribute (String,Object)方法。 所以对于一个布尔值,如果你想把它存储在一个http会话中,你不得不使用布尔类。

 HttpSession sess = request.getSession(false); Boolean isAdmin = (Boolean) sess.getAttribute("admin"); if (! isAdmin) ... 

如果未设置属性值,则最后一行将导致NullPointerException 。 (这是导致我这个职位的原因)。 所以3逻辑状态是留在这里,不pipe你喜欢用还是不用。

当你需要三个状态时,布尔值可以是非常有用的。 像在软件testing中一样,如果testing通过发送真,如果失败发送错误,如果testing用例中断发送空,这将表示testing用例不执行。

最好的办法是完全避免布尔值,因为每一个布尔值意味着你在代码中的任何地方都有一个条件语句(见http://www.antiifcampaign.com/和这个问题:; 你可以写任何没有if语句的algorithm? )。

但是,实际上你必须不时地使用布尔运算符,但是正如你自己已经发现的那样,处理布尔运算符更容易出错,也更麻烦。 所以我会build议尽可能使用布尔值。 从这个例外可能是一个遗留的数据库,可空布尔列,虽然我会试图隐藏在我的映射以及。