Java上Boolean.booleanValue函数的优点或用途?
我看到了这行代码:Java上Boolean.booleanValue函数的优点或用途?,java,boolean,wrapper,primitive,Java,Boolean,Wrapper,Primitive,我看到了这行代码: Boolean variable = false; /* ..stuff.. */ if(variable.booleanValue() == false) { /* ..more stuff..*/ } 我在另一个地方做过: Boolean variable = false; /* ..my stuff..*/ if(!variable) { /* ..more of my stuff..*/ } 问题是:第一段代码与第一段相比有什么区别/优势 长版本是:如果我可以将布
Boolean variable = false;
/* ..stuff.. */
if(variable.booleanValue() == false) {
/* ..more stuff..*/
}
我在另一个地方做过:
Boolean variable = false;
/* ..my stuff..*/
if(!variable) {
/* ..more of my stuff..*/
}
问题是:第一段代码与第一段相比有什么区别/优势
长版本是:如果我可以将布尔变量用作基本变量(布尔),那么执行variable.booleanValue()甚至将其与布尔值进行比较有什么意义?如果变量未初始化,这是否也会带来空指针异常的风险(在代码上是不可能的,但是嘿)
在任何情况下,建议在“变量”上方使用variable.booleanValue?这两个代码段的行为没有区别 : 在运行时,取消装箱转换按如下方式进行: 如果r是布尔类型的引用,则取消装箱转换将r转换为r.booleanValue() 因此,
if(variable){…}
将作为if(variable.booleanValue()){…}
执行。因为它们是完全等效的,所以如果variable==null
,它们都同样容易受到NPE的影响
这意味着显式调用booleanValue()
的一个可能的次要优点是,您可以立即看到variable
正在被取消引用,而variable==false
则不太明显
无论是添加==false
还是求反都是一个有趣的问题,我宁愿避免使用==
操作符将布尔表达式与true
或false
进行比较
但我认为更重要的是,您要完全避免使用
Boolean
,并尽可能使用原语类型 我认为第一种方法与第二种方法相比的唯一优势是,可以使用Java 1.5之前较旧的JDK/Java languaje规范编译代码Boolean
有三种状态-true
、false
和null
。如果您的in未初始化,那么在编写时,您将获得NullPointerException
!var
。
还要记住,对象自动初始化为
null
,而布尔基元自动初始化为false
,区别在于自动取消装箱
第一个版本,更好地编码为:
if (variable.booleanValue())
不需要自动取消装箱,因此可以与1.5版本之前的Java一起使用
第二个版本使用自动取消装箱,因此需要1.5及以上版本
如果需要在旧Java版本上运行代码,则必须使用版本1
两者都可以抛出NPE,因此在这一点上没有区别。指出了我能想到的唯一技术上有所不同的东西:第二个代码段依赖于,因此需要Java版本>=1.5
除此之外,没有技术上的区别。你提到
如果变量未初始化,这是否也会引入空指针异常的风险(在代码上是不可能的,但是嘿)
但是两个版本都是这样。当变量为null
时,即使第二个变量也会抛出NullPointerException
然而,我对这一点也很好奇,并做了一个测试:
public class TheManyShadesOfFasle
{
public static int testBoxedBooleanBooleanValueComparison()
{
Boolean variable = false;
if(variable.booleanValue() == false)
{
return 0;
}
return 1;
}
public static int testBoxedBooleanComparison()
{
Boolean variable = false;
if(variable == Boolean.FALSE)
{
return 0;
}
return 1;
}
public static int testBoxedBooleanBooleanValueDirect()
{
Boolean variable = false;
if(!variable.booleanValue())
{
return 0;
}
return 1;
}
public static int testBoxedBooleanDirect()
{
Boolean variable = false;
if(!variable)
{
return 0;
}
return 1;
}
public static int testBooleanComparison()
{
boolean variable = false;
if(variable == false)
{
return 0;
}
return 1;
}
public static int testBooleanDirect()
{
boolean variable = false;
if(!variable)
{
return 0;
}
return 1;
}
}
可以使用javap-c
对其进行反编译,以获得字节码:
public static int testBoxedBooleanBooleanValueComparison();
Code:
0: iconst_0
1: invokestatic #2 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
4: astore_0
5: aload_0
6: invokevirtual #3 // Method java/lang/Boolean.booleanValue:()Z
9: ifne 14
12: iconst_0
13: ireturn
14: iconst_1
15: ireturn
public static int testBoxedBooleanComparison();
Code:
0: iconst_0
1: invokestatic #2 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
4: astore_0
5: aload_0
6: getstatic #4 // Field java/lang/Boolean.FALSE:Ljava/lang/Boolean;
9: if_acmpne 14
12: iconst_0
13: ireturn
14: iconst_1
15: ireturn
public static int testBoxedBooleanBooleanValueDirect();
Code:
0: iconst_0
1: invokestatic #2 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
4: astore_0
5: aload_0
6: invokevirtual #3 // Method java/lang/Boolean.booleanValue:()Z
9: ifne 14
12: iconst_0
13: ireturn
14: iconst_1
15: ireturn
public static int testBoxedBooleanDirect();
Code:
0: iconst_0
1: invokestatic #2 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
4: astore_0
5: aload_0
6: invokevirtual #3 // Method java/lang/Boolean.booleanValue:()Z
9: ifne 14
12: iconst_0
13: ireturn
14: iconst_1
15: ireturn
public static int testBooleanComparison();
Code:
0: iconst_0
1: istore_0
2: iload_0
3: ifne 8
6: iconst_0
7: ireturn
8: iconst_1
9: ireturn
public static int testBooleanDirect();
Code:
0: iconst_0
1: istore_0
2: iload_0
3: ifne 8
6: iconst_0
7: ireturn
8: iconst_1
9: ireturn
可以看到testBoxedBooleanBooleanValueComparison
和testBoxedBooleanDirect
(对应于第一个和第二个代码段)的字节码是相同的。(这基本上意味着:自动取消装箱是在内部隐式调用booleanValue
方法的Boolean
)。如果(!variable.booleanValue()),则与相同,如testBoxedBooleanBooleanValueDirect
中所示
其他情况主要是为了完整性而存在的:testBooleanComparison
和testBooleanDirect
情况都具有相同的字节码,但它与其他情况不同,因为没有进行拆箱或解除隔离
有一种情况可能值得指出:将变量与Boolean.FALSE
或Boolean.TRUE
进行比较是有意义的,因为它隐含了变量为null
的情况:
if (variable == Boolean.TRUE) {
...
} else {
// Here, the variable is either "false" or "null"
}
vs
空指针异常的风险也在第二个片段中,只是伪装,所以人们可能认为它仍然值得。不过,我喜欢第二种。我非常不喜欢将布尔值与==true
或==false
进行比较。不,我想不出一个我想显式调用booleanValue()
的例子。如前所述,这里的状态使用装箱/取消装箱。实际上,它与Boolean val=Boolean.FALSE(或TRUE)相同,可以使用取消绑定为TRUE/FALSE的原始状态,这与调用对象上的.booleanValue()相同-如果您想在web应用程序单选按钮中声明-Null,真/假还有很多其他的,但这是我们使用它的主要原因。+1正如它提到的,解装箱/装箱被用于从原始状态派生对象布尔值。谢谢!我不知道booleanValue是自动调用的(因此,我根本不知道函数的意义,因为我认为它是某种低级java魔法)。我尽量避免使用这种包装,但你知道,我无法接触到继承的代码。
if (variable == Boolean.FALSE) {
...
} else {
// Here, the variable is either "true" or "null"
}