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"
}