161

Javaboolean允许 和 的值,truefalse布尔值允许true,falsenull. 我已经开始将我boolean的 s 转换为Booleans。这可能会导致测试崩溃,例如

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

而测试

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

似乎做作且容易出错。

什么时候,如果有的话,将Booleans 与空值一起使用是否有用?如果从来没有,那么包裹对象的主要优点是什么?

更新:有很多有价值的答案,我在自己的答案中总结了一些。我充其量只是 Java 的中级,所以我试图展示我认为有用的东西。请注意,问题是“措辞不正确”(布尔值不能“具有空值”),但我将其保留以防其他人有同样的误解

4

14 回答 14

249

使用boolean而不是Boolean每次都使用。这将避免许多NullPointerExceptions 并使您的代码更加健壮。

Boolean很有用,例如

  • 将布尔值存储在集合中(列表、地图等)
  • 表示一个可为空的布尔值(例如,来自数据库中的一个可为空的布尔值列)。在这种情况下,空值可能意味着“我们不知道它是真还是假”。
  • 每次方法需要一个对象作为参数时,您都需要传递一个布尔值。例如,当使用反射或类似MessageFormat.format().
于 2012-06-25T07:53:24.377 回答
59

我几乎从不使用Boolean,因为它的语义模糊不清。基本上你有三态逻辑:真、假或未知。有时,当您让用户在两个值之间进行选择并且用户根本没有回答并且您真的想知道该信息时使用它很有用(想想:NULLable 数据库列)。

我认为没有理由从 to 转换booleanBoolean因为它引入了额外的内存开销、NPE 可能性和更少的输入。通常我会使用尴尬BooleanUtils.isTrue()来让我的生活更轻松Boolean

存在的唯一原因Boolean是能够拥有Boolean类型的集合(泛型不允许boolean,以及所有其他原语)。

于 2012-06-25T07:53:16.100 回答
33

哇,到底是什么?只是我还是所有这些答案都是错误的或至少具有误导性?

Boolean 类是 boolean 原始类型的包装器。此包装器的用途是能够在接受对象或泛型的方法中传递布尔值。即向量。

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

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

空布尔引用仅应用于触发您有任何其他空引用的类似逻辑。将它用于三态逻辑是笨拙的。

编辑:注意,这Boolean a = true;是一个误导性的陈述。这真的等于更接近Boolean a = new Boolean(true); 请在此处查看自动装箱:http ://en.wikipedia.org/wiki/Boxing_%28computer_science%29#Autoboxing

也许这就是很多混乱的来源。

EDIT2:请阅读下面的评论。如果有人知道如何重组我的答案以纳入这一点,请这样做。

于 2012-06-25T14:42:55.583 回答
26

有三个快速的原因:

  • 表示数据库布尔值,可以是truefalsenull
  • 表示用声明的 XML Schema 的xsd:booleanxsd:nillable="true"
  • 能够使用泛型类型:List<Boolean>- 你不能使用List<boolean>
于 2012-06-25T07:52:39.847 回答
11

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

  • 空“值”不是一个值,与 and 根本true不同false。这是没有指向对象的指针。因此认为布尔值是 3 值是根本错误的
  • Boolean 的语法被缩写并隐藏了引用指向对象的事实:

    Boolean a = true;

true掩盖了它是一个对象的事实。其他等效的分配可能是:

Boolean a = Boolean.TRUE;

或者

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

    if (a) ...

与大多数其他赋值不同,并隐藏了 a 可能是对象引用或原语的事实。如果一个对象有必要进行测试null以避免NPE。对我来说,如果有平等测试,在心理上更容易记住这一点:

if (a == true) ...

我们可能会被提示测试是否为空。所以缩短的形式只有在a是原语时才是安全的。

对于我自己,我现在有以下建议:

  • 切勿将 null 用于 3 值逻辑。只用真假。
  • 永远不要从一个方法返回Boolean,因为它可能是null。只有返回boolean
  • Boolean用于将元素包装在容器中,或用于需要对象的方法的参数
于 2012-06-26T17:19:23.970 回答
10

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

想象一下,由于某种原因,您需要存储一个booleanin 的序列ArrayList,这可以通过装箱来boolean完成Boolean

这里有几句话

从文档:

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

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

于 2012-06-25T07:52:54.437 回答
3

我想在某些情况下,您应该有一种机制来区分已经设置值与否的布尔字段。

于 2012-06-25T07:52:56.857 回答
3

Booleantrue当您想要除and之外是否分配了值时,包装器很有用false。它有以下三种状态:

  • 真的
  • 错误的
  • 未定义哪个是null

boolean只有两种状态:

  • 真的
  • 错误的

上述差异将使其在Boolean值列表中有所帮助,其中可以有TrueFalseNull

于 2012-06-25T07:53:20.460 回答
1

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

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

Boolean set = Boolean.FALSE; //set to default value primitive value (false)
...
if (set) ...
于 2012-06-25T07:54:08.950 回答
1

布尔包装器中的 **null** 值有很多用途!:)

例如,您可能在表单中有一个名为“newsletter”的字段,该字段指示用户是否想要来自您的站点的时事通讯。如果用户未在此字段中选择值,您可能希望针对该情况实施默认行为(发送?不发送?,再次提问?等)。显然,未设置(或未选中或**null**),不等于true或false。

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

于 2012-06-26T22:24:29.227 回答
1

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

因此,在我们生活的不完美世界中,布尔对象非常棒,因为它可以将缺失或未知状态表示为空。毕竟,计算机只是对现实世界进行建模,应该考虑所有可能的状态并通过抛出异常来处理它们(主要是因为在某些用例中抛出异常是正确的响应)。

就我而言,布尔对象是完美的答案,因为输入 XML 有时会丢失元素,我仍然可以获得一个值,将其分配给布尔值,然后在尝试对其使用真假测试之前检查是否为空.

只是我的2美分。

于 2014-01-23T17:25:35.537 回答
1

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

如果您需要为会话存储和检索值,请使用setAttribute(String, Object) 和getAttribute(String, Object) 方法。因此,对于布尔值,如果要将其存储在 http 会话中,则必须使用 Boolean 类。

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

NullPointerException如果未设置属性值,最后一行将导致 a 。(这就是导致我写这篇文章的原因)。因此,无论您是否喜欢使用它,这 3 个逻辑状态都将保留。

于 2015-07-04T18:56:03.710 回答
1

当您需要三种状态时,布尔值非常有用。就像在软件测试中一样,如果测试通过发送 true,如果失败发送 false,如果测试用例中断发送 null,这将表示测试用例未执行。

于 2016-01-11T17:27:27.070 回答
0

最好的方法是完全避免布尔值,因为每个布尔值都意味着您在代码中的其他任何地方都有一个条件语句(请参阅http://www.antiifcampaign.com/和这个问题:Can you write any algorithm without an if statement ? )。

但是,务实地你必须不时使用布尔值,但是,正如你自己已经发现的那样,处理布尔值更容易出错,也更麻烦。所以我建议尽可能使用布尔值。例外情况可能是具有可为空布尔列的旧数据库,尽管我也会尝试将其隐藏在我的映射中。

于 2012-06-25T07:57:57.850 回答