什么时候应该使用Boolean的null值?

时间:2012-06-25 07:46:57

标签: java boolean

Java boolean允许truefalse的值,而布尔允许truefalsenull。我已开始将boolean转换为Boolean s。这可能会导致测试中的崩溃,例如

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

而考试

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

似乎很做作,容易出错。

如果有的话,将Boolean用于空值是否有用?如果从来没有,那么被包裹物体的主要优点是什么?

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

14 个答案:

答案 0 :(得分:238)

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

Boolean很有用,例如

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

答案 1 :(得分:53)

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

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

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

答案 2 :(得分:31)

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

Boolean类是布尔基元类型的包装器。使用此包装器是为了能够在接受对象或泛型的方法中传递布尔值。即矢量。

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

您可能会觉得这很有用: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

也许这就是大部分混乱的来源。

EDIT2:请阅读以下评论。 如果有人知道如何重新构建我的答案以便合并它,请这样做。

答案 3 :(得分:24)

有三个快速原因:

  • 表示数据库布尔值,可以是truefalsenull
  • 表示使用xsd:boolean
  • 声明的XML Schema的xsd:nillable="true"
  • 能够使用泛型类型:List<Boolean> - 您无法使用List<boolean>

答案 4 :(得分:11)

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

  • null“value”不是值,与truefalse根本不同。缺少指向对象的指针。因此认为布尔值是3值是根本错误的
  • Boolean的语法是缩写的,并隐藏了引用指向Objects:

    的事实

    Boolean a = true;

隐瞒了true是一个对象的事实。其他等效作业可能是:

Boolean a = Boolean.TRUE;

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

    if (a) ...

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

if (a == true) ...

我们可能会提示我们测试null。因此,当a是基元时,缩短的形式才是安全的。

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

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

答案 5 :(得分:10)

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

想象一下,出于某种原因,您需要在boolean中存储一系列ArrayList,这可以通过在boolean中装箱Boolean来完成。

关于这个here

,有几句话

来自文档:

  

正如任何Java程序员所知,你不能放一个int(或其他原语   价值)成一个集合。集合只能保存对象引用,   所以你必须将原始值包装到适当的包装类中   (在int的情况下是Integer)。当你取出物体时   收集,你得到你输入的整数;如果你需要一个   int,您必须使用intValue方法取消对Integer的打开。所有这些   装箱和拆箱是一种痛苦,并使你的代码变得混乱。该   自动装箱和拆箱功能使过程自动化,消除了   痛苦和杂乱。

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

答案 6 :(得分:3)

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

答案 7 :(得分:3)

当您想要分配值是否与Booleantrue分开时,

false包装器非常有用。它有以下三种状态:

  • 未定义哪个是null

boolean只有两种状态:

上述差异将有助于列出Boolean值,TrueFalseNull

答案 8 :(得分:1)

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

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

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

答案 9 :(得分:1)

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

例如,您可能会在表单中添加一个名为“简报”的字段,指明用户是否想要您网站上的简报。如果用户未在此字段中选择值,您可能希望对该情况实施默认行为(发送?不发送?,再次提问?等)。显然,未设置(或未选中或** null **)与真或假不一样。

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

答案 10 :(得分:1)

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

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

在我的例子中,布尔对象是完美的答案,因为输入XML有时会丢失元素,我仍然可以得到一个值,将它分配给一个布尔值,然后在尝试使用true或false之前检查null用它来测试。

只需2美分。

答案 11 :(得分:1)

对于上面的所有好答案,我将在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逻辑状态都会存在。

答案 12 :(得分:1)

当您需要三个状态时,布尔值非常有用。就像在软件测试中一样,如果传递了Test,则发送为true,如果失败则发送false,如果测试用例中断,则发送null,表示测试用例未执行。

答案 13 :(得分:0)

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

然而,实际上你必须不时地使用布尔值,但是,正如你自己已经发现的那样,处理布尔值更容易出错并且更加繁琐。所以我建议尽可能使用布尔值。例外情况可能是具有可空布尔列的遗留数据库,尽管我也会尝试在我的映射中隐藏它。