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

pet*_*ust 157 java boolean

Java的boolean允许值true,并false同时允许布尔值true,falsenull.我已经开始将我的booleans 转换为Booleans.这可能导致测试中的崩溃,例如

Boolean set = null;
...
if (set) ...
Run Code Online (Sandbox Code Playgroud)

而考试

if (set != null && set) ...
Run Code Online (Sandbox Code Playgroud)

看似人为,容易出错.

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

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

JB *_*zet 240

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

Boolean 例如,有用

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

  • 数据库中的空值也可能意味着["FileNotFound"](http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx) (35认同)
  • 我认为你的第二颗子弹确实是这个问题的正确答案的核心. (31认同)
  • 或#4:`布尔isSchrodinger CatAlive = null;`(对不起,无法抗拒;)). (16认同)
  • 使用除"宇宙不知道"以外的含义重载null的概念,它比使用3(或更多)值enum弱.使读取代码也更明确地将参数传递给方法. (6认同)
  • 我所拥有的布尔的另一个用途是在扩展泛型类时作为泛型类型参数 - 与第3点密切相关. (3认同)
  • @jonnyGold:使用3值枚举的最好的事情是你得到一个免费的第四个状态(null).;) (2认同)

Tom*_*icz 58

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

我看不出有任何理由要转换booleanBoolean,因为它引入了额外的内存开销,NPE可能性少打字.通常情况下,我使用笨拙的BooleanUtils.isTrue()方式让我的生活变得更轻松Boolean.

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

  • 使用Boolean时,一个方便的测试来避免空指针异常是[`Boolean.TRUE.equals(myBooleanObject)`](http://docs.oracle.com/javase/6/docs/api/java/lang/Boolean. html#equals(java.lang.Object))或`Boolean.FALSE.equals(myBooleanObject)`. (38认同)
  • 我没遇到的`BooleanUtils.isTrue()`的+1 (10认同)
  • 布尔对象只有两种状态 - "true"和"false".`null`是***不是***对象的状态,而是对象引用的状态. (10认同)
  • 对于多值逻辑,最好使用枚举.因此,布尔值应留给(自动)装箱变量以用于数据结构. (4认同)
  • 留给apache公共就像"有人可能搞砸了评价布尔......让我们制作一个`isTrue()`方法......"这听起来像是效用函数历史上最蠢的怪物.然而,不知何故,它是有用的...这是最重要的wtf. (2认同)

use*_*723 32

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

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

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

编辑2:请阅读以下评论.如果有人知道如何重新构建我的答案以便合并这个,请这样做.

  • 当你做'布尔a`; a是指向Boolean对象的指针.如果你是'a = null;`你没有将你的布尔值设置为null,那么你已经将引用设置为null.做`布尔a = null; a.booleanValue();`在这种情况下,你***甚至从未创建过***一个布尔对象,因此它会抛出一个nullpointerexception.如果您需要进一步的指导,请告诉我. (7认同)
  • @missingno,处理任何对象的所有代码都必须处理这个问题.对象引用可以为null或不为null.这不是特殊情况,不需要特别考虑. (7认同)
  • 你错过了我的观点@missingno.我同意我们需要考虑空参考值.我从来没有反对过这个问题.但我们需要为**任何对象引用执行此操作.**null布尔引用不是特殊情况.因此,null布尔参考值不需要特别考虑. (3认同)
  • 我不明白你的陈述"布尔值永远不会有null值".我可以创建一个布尔值(`Boolean a = true;`),然后将a设置为null(`a = null;`).它可能不是优雅或明智的,但它是可能的. (2认同)

Grz*_*bek 24

有三个快速原因:

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

  • 什么数据库不允许null为布尔值?如果将列设置为可为空,则数据类型不再重要... (2认同)

pet*_*ust 11

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

  • 空"值"是不是值,是从根本上不同的truefalse.缺少指向对象的指针.因此认为布尔值是3值是根本错误的
  • Boolean的语法是缩写的,并隐藏了引用指向Objects的事实:

    Boolean a = true;

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

Boolean a = Boolean.TRUE;
Run Code Online (Sandbox Code Playgroud)

要么

Boolean a = new Boolean(true);
Run Code Online (Sandbox Code Playgroud)
  • 缩写语法

    if (a) ...

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

if (a == true) ...

我们可能会提示我们测试null.所以缩短的形式只有在a原始时才是安全的.

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

  • 切勿对3值逻辑使用null.只使用真假.
  • 永远不要Boolean从方法中返回null.只有回归boolean.
  • Boolean用于在容器中包装元素,或者用于需要对象的方法的参数

  • 不要使用"new Boolean(whatever)".这将在堆上实例化一个新的布尔值.然而,布尔是不可改变的.使用"Boolean.valueOf(whatever)"将创建一个指向Boolean.TRUE或Boolean.False的引用,具体取决于任何内容. (4认同)

Fra*_*eth 10

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

想象一下,你需要某种原因商店的序列boolean中的ArrayList,这可以通过拳击来完成booleanBoolean.

有关于这几句话在这里

来自文档:

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

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