java - 什么时候应该使用Boolean的null值?
Java boolean允许值Boolean和false,而布尔值允许true,false和null.我已经开始将booleans转换为Booleans。 这可能导致测试中的崩溃,例如
Boolean set = null;
...
if (set) ...
而考试
if (set != null && set) ...
看似人为,容易出错。
如果有的话,使用带有空值的Booleans是否有用? 如果从来没有,那么被包裹物体的主要优点是什么?
更新:有很多有价值的答案,我在自己的答案中总结了一些。 我充其量是Java的中间人,所以我试图展示我发现有用的东西。 请注意,问题是“错误的措辞”(布尔值不能“具有空值”),但我已经离开它以防其他人有相同的误解
14个解决方案
234 votes
每次都可以使用MessageFormat.format()而不是Boolean。 这将避免许多NullPointerException并使您的代码更健壮。
例如,MessageFormat.format()很有用
在集合中存储布尔值(列表,地图等)
表示可以为空的布尔值(例如,来自数据库中可以为空的布尔列)。 在此上下文中,null值可能意味着“我们不知道它是真还是假”。
每次方法需要Object作为参数时,您需要传递一个布尔值。 例如,使用反射或方法如MessageFormat.format()。
JB Nizet answered 2019-04-30T06:46:03Z
52 votes
我几乎从不使用Boolean,因为它的语义模糊不清。 基本上你有三态逻辑:真,假或未知。 有时在例如使用它时很有用。 您为用户提供了两个值之间的选择,而用户根本没有回答,您真的想知道这些信息(想想:NULLable数据库列)。
我认为没有理由将Boolean转换为Boolean,因为它引入了额外的内存开销,NPE可能性和更少的输入。 通常我使用尴尬的Boolean来使我的生活更轻松boolean。
存在Boolean的唯一原因是能够拥有Boolean类型的集合(泛型不允许boolean,以及所有其他基元)。
Tomasz Nurkiewicz answered 2019-04-30T06:46:50Z
31 votes
哇,到底是什么? 它只是我或所有这些答案是错误的还是至少误导?
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:请阅读以下评论。如果有人知道如何重新构建我的答案以便合并这个,请这样做。
user606723 answered 2019-04-30T06:48:15Z
24 votes
有三个快速原因:
表示数据库布尔值,可能是List,List或null
表示使用List声明的XML Schema的List值
能够使用泛型类型:List - 你不能使用List
Grzegorz Grzybek answered 2019-04-30T06:49:10Z
11 votes
回答所有问题:我认为回答我自己的问题是有用的,因为我从答案中学到了很多东西。 这个答案旨在帮助像我这样的人,他们对这些问题没有完全的了解。 如果我使用不正确的语言,请纠正我。
null“value”不是值,并且与Boolean和null根本不同。缺少指向对象的指针。 因此认为布尔值是3值是根本错误的
Boolean的语法是缩写的,并隐藏了引用指向Objects的事实:
Boolean
隐瞒Boolean是一个对象的事实。 其他等效作业可能是:
Boolean a = Boolean.TRUE;
要么
Boolean a = new Boolean(true);
缩写语法
Boolean
与大多数其他赋值不同,并隐藏了a可能是对象引用或原语的事实。 如果对象有必要测试Boolean以避免NPE。 对我来说,如果有一个相等的测试,在心理上更容易记住这个:
Boolean
我们可能会提示我们测试null。 因此,当Boolean是基元时,缩短的形式才是安全的。
对我自己,我现在有了建议:
切勿对3值逻辑使用null。 只使用真假。
永远不要从方法返回Boolean,因为它可能是null.仅返回boolean。
仅使用Boolean包装容器中的元素,或者使用需要对象的方法的参数
peter.murray.rust answered 2019-04-30T06:51:07Z
10 votes
可以在需要对象的地方使用基元的包装类,集合是一个很好的样本。
想象一下,你需要出于某种原因在ArrayList中存储boolean的序列,这可以通过在Boolean中装箱boolean来完成。
这里有几句话
来自文档:
正如任何Java程序员所知,你不能放一个int(或其他原语 价值)成一个集合。 集合只能保存对象引用, 所以你必须将原始值包装到适当的包装类中 (在int的情况下是Integer)。 当你取出物体时 收集,你得到你输入的整数; 如果你需要一个 int,您必须使用intValue方法取消对Integer的打开。 所有这些 装箱和拆箱是一种痛苦,并使你的代码变得混乱。该 自动装箱和拆箱功能使过程自动化,消除了 痛苦和杂乱。
[http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html]
Francisco Spaeth answered 2019-04-30T06:52:11Z
3 votes
Boolean包装器在您想要是否分配值时非常有用,除了True和False之外。它有以下三种状态:
真正
假
未定义的是Boolean
而Boolean只有两种状态:
真正
假
以上差异将使其在Boolean值的列表中有所帮助,其可以具有True,False或Null。
Ramesh PVK answered 2019-04-30T06:53:13Z
3 votes
我想在某些情况下,您应该有一种机制来区分已设置值的布尔字段。
Thinhbk answered 2019-04-30T06:53:46Z
1 votes
布尔值的主要用途是空值。 空值表示,该属性未定义,例如取数据库可空列。
如果你真的需要将所有内容从原始布尔值转换为包装器布尔值,那么你可以使用以下来支持旧代码:
Boolean set = Boolean.FALSE; //set to default value primitive value (false)
...
if (set) ...
JMelnik answered 2019-04-30T06:54:29Z
1 votes
布尔包装器中的** null **值有很多用途!:)
例如,您可能在表单中有一个名为“newsletter”的字段,表明用户是否想要您网站上的简报。 如果用户未在此字段中选择值,您可能希望对该情况实施默认行为(发送?不发送?,再次提问?等)。 显然,未设置(或未选择或** null **)与true或false不同。
但是,如果“未设置”不适用于您的模型,请不要更改布尔基元;)
dcasanueva answered 2019-04-30T06:55:18Z
1 votes
在布尔元素的严格定义中,只有两个值。 在一个完美的世界里,那是真的。 在现实世界中,元素可能缺失或未知。 通常,这涉及用户输入。 在基于屏幕的系统中,可以通过编辑强制它。 在使用数据库或XML输入的批处理世界中,该元素很容易丢失。
因此,在我们生活的非完美世界中,布尔对象很棒,因为它可以将缺失或未知状态表示为null。 毕竟,计算机只是模拟现实世界,应该考虑所有可能的状态,并通过抛出异常来处理它们(主要是因为有用例抛出异常将是正确的响应)。
在我的例子中,布尔对象是完美的答案,因为输入XML有时会丢失元素,我仍然可以得到一个值,将它分配给一个布尔值,然后在尝试使用true或false测试之前检查null。
只需2美分。
user3228876 answered 2019-04-30T06:56:09Z
1 votes
对于上面的所有好答案,我将在Java servlet NullPointerException类中给出一个具体的例子。 希望这个例子有助于澄清你可能仍然存在的一些问题。
如果需要存储和检索会话的值,请使用NullPointerException(String,Object)和getAttribute(String,Object)方法。 因此,对于布尔值,如果要将其存储在http会话中,则必须使用布尔类。
HttpSession sess = request.getSession(false);
Boolean isAdmin = (Boolean) sess.getAttribute("admin");
if (! isAdmin) ...
如果未设置属性值,则最后一行将导致NullPointerException。 (这是导致我这篇文章的原因)。 因此,无论您是否喜欢使用它,3逻辑状态都将保留。
Wacker answered 2019-04-30T06:57:00Z
1 votes
当您需要三个状态时,布尔值非常有用。 就像在软件测试中一样,如果传递了Test,则发送为true,如果失败则发送false,如果测试用例中断,则发送null,表示测试用例未执行。
Aamir answered 2019-04-30T06:57:34Z
0 votes
最好的方法是完全避免布尔值,因为每个布尔值都意味着你的代码中的其他任何地方都有一个条件语句(参见[http://www.antiifcampaign.com/]和这个问题:你能不写任何算法吗? 如果声明?)。
但是,实际上你必须时不时地使用布尔值,但是,正如你自己已经发现的那样,处理布尔值更容易出错并且更加繁琐。 所以我建议尽可能使用布尔值。 这样的例外可能是具有可以为空的布尔列的遗留数据库,尽管我也会尝试在我的映射中隐藏它。
Roland Schneider answered 2019-04-30T06:58:23Z