我有以下代码:
Boolean bool = null;
try
{
if (bool)
{
//DoSomething
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
为什么检查布尔变量" bool"会导致异常?
当它"看到"这不是事实时,它不应该跳过if语句吗?
当我删除if语句或检查它是否不为null时,该异常消失了。
上面有关对象拆箱的答案都是正确的。 但是,出于完整性考虑,您还可以将代码更改为使用原始" boolean"而不是对象包装" Boolean"。 您还应该刷新原始对象和对象之间的区别。
同时... if (bool == Boolean.TRUE)评估为false而不生成异常。 不知道在我刚刚发现的情况下这是否是故意的。
@ simon.watts对于bool为null或如果Boolean是显式构造的(而不是作为Boolean.TRUE的引用)将为false。 所以不推荐; 与if (Boolean.TRUE.equals(bool))可以正常工作的相反,包括安全地处理null值。
如果您不喜欢多余的null检查:
if (Boolean.TRUE.equals(value)) {...}
@AvrDragon:是否等于要求?运算符==在这里有效,因为布尔值只有两个值
@Atul是的,这里等于。因为(new Boolean(true)== new Boolean(true))是...原因:布尔值只是一个类,可以像Java中的任何其他类一样具有多个实例。
是的,那太可惜了,构造函数应该是私有的,以确保其闪烁...
@fortran +1表示" twingleton"。
当我对我的代码进行详细的空检查感到沮丧时,Ive多次发现此答案很有用。希望我每次都能+1。
这正是Apache BooleanUtils BooleanUtils.isTrue( bool );所做的。
好一个,因为我不喜欢额外的空值检查
在这个习语上使用Apache BooleanUtils绝对没有意义。
当您拥有boolean时,它可以是true或false。但是,当您拥有boolean时,它可以是Boolean.TRUE,Boolean.FALSE或null作为任何其他对象。
在您的特定情况下,您的boolean是null,并且if语句触发对生成NullPointerException的boolean的隐式转换。您可能需要:
if(bool != null && bool) { ... }
从技术上讲,Boolean可以是任意数量的真实实例,而不仅仅是Boolean.TRUE。例如new Boolean(true)。
我很难理解为什么if (myBoolean)(其中myBoolean是Boolean)没有引发编译器错误或至少没有警告。这肯定是一个陷阱。
@JoshM。这是因为Java会对包装程序进行装箱和拆箱:docs.oracle.com/javase/tutorial/java/data/autoboxing.html
@Vinicius可以肯定,但是在这种情况下,编译器应该为我们做空(至少通过编译器警告发出)。
@JoshM。不能同意更多:)
使用Apache BooleanUtils。
(如果峰值性能是项目中最重要的优先事项,那么请查看不需要包含外部库的本机解决方案的其他答案之一。)
不要重新发明轮子。利用已经构建的内容并使用isTrue():
BooleanUtils.isTrue( bool );
检查boolean值是否为true,并通过返回false处理null。
如果您不仅仅局限于"允许"包含的库,那么对于各种用例(包括Booleans和Strings),都有大量的好帮手功能。我建议您仔细阅读各种Apache库,看看它们已经提供了什么。
当替代方法是使用外部库来实现这种基本功能时,重新发明轮子似乎并不那么糟糕。
@PaulManta我同意这是否是您在Apache Utils库中唯一使用过的东西,但是建议的想法是"细读"这些库以使自己接触到其他有用的功能。
使用这些库会降低性能。因此,对于这种语言的基本内容,您不应使用库。
@Vlad就像我写给PaulManta的信一样,我同意,如果这是您唯一要使用此库的东西,那么它的性能和"膨胀"值并不值得,但经常会使您接触到其他可以使用的辅助函数,使包含物值得一试。
@Josh Pinter不仅关系到包含的权重,而且关系到调用该实用程序函数的开销。有时间和空间的惩罚。
那个图书馆正在重新发明轮子。我试图尽可能避免使用此类库。
@mschonaker如果Apache BooleanUtils重新发明了轮子,那么原来的轮子是什么?这样做的目的是避免创建一堆辅助函数,以模仿诸如此类的库中已经完成的工作。我还在所有应用程序中都使用了该库中的toStringYesNo。
包括整个库来获得该功能不是正确的选择。
原始的车轮不是Boolean.TRUE.equals(bool)吗? BooleanUtils中肯定有一些有用的方法,但是您不需要它。
@nnnnnn绝对不需要它。 只是另一个选择。 以及Apaches实用程序库的介绍(针对那些未启动的库)。
BooleanUtils代码说:return bool.booleanValue() ? true : false;冗余吗? 是为了提高可读性吗?
boolean类型可以是null。将null设置为null时,需要进行检查。
if (bool != null && bool)
{
//DoSomething
}
这个答案有什么问题?不是检查将引发异常的布尔值。不必要的降票。
我同意这是一个完全合理的答案。但是您可以摆脱异常处理。
异常处理是不必要的,此外,异常处理对初学者来说是一个不好的例子。这值得一提,IMO。 (是的...我知道它来自示例代码,但是在"答案"中重复此代码似乎可以认可它。)
那么正确的方法是什么?我在这里看不到你的答案。
正确的方法是上述方法。没有异常处理。另外,异常处理太笼统了,不建议使用。
讨论正确或错误的方法是模糊的。
布尔值是原始布尔值的对象包装器类。与任何类一样,此类实际上可以为null。出于性能和内存方面的原因,始终最好使用原语。
Java API中的包装器类有两个主要用途:
提供一种在对象中"包装"原始值的机制,以便
可以将原语包含在为以下内容保留的活动中
对象,例如添加到"收藏夹"或从
对象返回值的方法。
提供各种各样的
原始函数。这些功能大多数是
与各种转换有关:将原语与来回转换
字符串对象,并将原语和字符串对象转换为和
来自不同的基数(或基数),例如二进制,八进制和
十六进制。
http://en.wikipedia.org/wiki/Primitive_wrapper_class
借助Java 8 Optional的强大功能,您还可以执行以下操作:
Optional.ofNullable(boolValue).orElse(false)
:)
由于您的变量bool指向空值,您将始终获得NullPointerException,您需要先使用非null值初始化变量,然后再对其进行修改。
如果仅此原因,catch块将处理NullPointerException。这里的问题是OP尝试将空引用拆箱到原语中。
"您将永远"-除示例外,并非总是如此,简化的代码在将变量初始化为null然后对其进行测试之间没有任何作用。大概真实的代码不会那么简单,也不会删除整个if测试。