Java中的布尔值与布尔值


194

关于Java中Integervs的讨论int。前者的默认值为,null而后者为0。如何BooleanVS boolean

我的应用程序中的变量可以具有0/ 1值。我想使用boolean/ Boolean而不愿意使用int。我可以使用Boolean/ boolean代替吗?


2
出于系统设计的原因,我将选择Boolean,因为它具有“用户尚未决定”选项,该选项既不等于“ true”,也不等于“ false”。仅在我100%确信true / false选项足够的情况下,我才使用布尔基元。在数据库中,通常可以毫无问题地使用NULL选项(或通过仅删除稍后需求的NOT NULL限制)
CsBalazsHungary 2014年

2
精确重复的内容Java中的boolean和Boolean什么区别?(因为GWT不会有所作为)。
Dan Dascalescu '16

Answers:


269

是的,您可以使用Boolean/ boolean代替。

第一个是对象,第二个是原始类型。

  • 首先,您将获得更多有用的方法。

  • 考虑内存开销 ,第二个便宜,第二个可以为您节省更多的内存,因此

现在选择您的方式。


70
您可能将其表述为“第二个将为您节省更多的内存,所以继续吧”。关于布尔的有用方法通常可以在没有实例的情况下被调用。
DJClayworth

3
只要使用新的Boolean(value)的Boolean.valueOf(value)代替,内存就不必担心。
格雷格案

2
为此AsyncTask,您只能使用Boolean代替boolean
猛禽2014年

98
应该注意的是,布尔实际上具有3个状态... truefalsenull布尔具有逻辑2个状态(truefalse
尊重TheCode 2014年

14
布尔值是trillean :)
Topera,

50

Boolean 包装布尔型基本类型。在JDK 5及更高版本中,Oracle(或Oracle在Oracle收购Sun之前)引入了autoboxing / unboxing功能,从本质上讲,您可以执行此操作

boolean result = Boolean.TRUE;

要么

Boolean result = true; 

实质上,编译器会这样做,

Boolean result = Boolean.valueOf(true);

因此,对于您的答案,是的。


4
注意:您不能总是安全地将分配Booleanboolean。如果您Boolean是,null并且您尝试将其分配给boolean,则会NullPointerException在运行时抛出。
邓肯·卢克

如果Boolean是一个类,那么即使我将另一个类的值更改为引用相同的布尔变量,为什么值始终为false?这个又是什么的地步Boolean,然后,如果我们不能从不同的实例类参考/传递作为参数?
user924 '18

找到了答案,我们可以使用AtomicBoolean差异类来引用它
user924 '18

35

我伸出提供的答案有点(因为到目前为止,他们专注于“自己” /人工术语专注于编程特定的语言,而不是照顾大局观的幕后制作的编程语言,在一般情况下,即当事情例如类型安全性与内存注意事项的区别):

int不是布尔值

考虑

    boolean bar = true;      
    System.out.printf("Bar is %b\n", bar);
    System.out.printf("Bar is %d\n", (bar)?1:0);
    int baz = 1;       
    System.out.printf("Baz is %d\n", baz);
    System.out.printf("Baz is %b\n", baz);

带输出

    Bar is true
    Bar is 1
    Baz is 1
    Baz is true

第3行上的Java代码(bar)?1:0说明,不能将barboolean)隐式转换(转换)为int。我提出这一点并不是为了说明JVM背后的实现细节,而是要指出,就低级考虑(作为内存大小)而言,人们确实比值安全更喜欢值。特别是如果没有像布尔类型那样真正/完全使用类型安全性,而布尔类型以

如果值\ in {0,1},则强制转换为布尔类型,否则抛出异常。

所有人只是说{0,1} <{-2 ^ 31,..,2 ^ 31 -1}。看起来像是过分杀伤了吧?类型安全对于用户定义的类型确实很重要,而不是对基元的隐式转换(尽管最后一个包含在第一个中)不是真正重要的。

字节不是类型或位

请注意,在内存中,{0,1}范围内的变量仍将至少占据一个字节或一个字(x位,取决于寄存器的大小),除非特别注意(例如,很好地包装在内存中-8个“布尔值”位变成1个字节-来回)。

通过优先于类型安全性(例如,将值放入/包装到特定类型的盒子中)而不是额外的值打包(例如,使用移位或算术),人们确实选择了编写更少的代码而不是获得更多的内存。(另一方面,总是可以定义一个自定义用户类型,这将促进所有不值得布尔值的转换)。

关键字与类型

最后,您的问题是关于比较关键字类型。我认为,重要的是要解释为什么/不通过使用关键字(“标记为原始 ”的关键字)优先于类型(使用其他关键字类的常规复合用户可定义的类)或换句话说,您将获得性能的原因或精确程度,

boolean foo = true;

Boolean foo = true;

第一个“事物”(类型)不能被扩展(子类化),并且并非没有原因。实际上,可以将原始类和 包装类的Java术语简单地转换为内联值(一个LITERAL或一个常量,只要有可能推断出替代,或者如果不能替代,则直接由编译器替代-仍然回退到包装值中)。

优化是由于琐碎的:

“更少的运行时转换操作=>更快的速度。”

这就是为什么当完成实际的类型推断时,如果有必要的话,它可能(仍然)最终用所有类型信息实例化包装类(或将其转换/转换为此类)。

因此,布尔值布尔值之间的区别恰好在编译运行时(虽然有点远,但几乎与instanceofgetClass()一样)。

最后,自动装箱比原始装箱慢

注意Java可以自动装箱的事实只是“语法糖”。它不会加快任何速度,只是允许您编写更少的代码。而已。仍将类型转换和包装到类型信息容器中。出于性能原因,请选择算法,该算法将始终跳过使用类型信息创建类实例以实现类型安全性的额外工作。缺乏类型安全性是您获得性能所需付出的代价。对于具有布尔值表达式的代码,类型安全(当您编写更少因而隐式代码时)对于例如if-then-else流控制至关重要。


16

您可以使用布尔常量 - Boolean.TRUEBoolean.FALSE代替0and 1boolean如果要使用原始变量,则可以按类型创建变量。这样,您就不必创建新Boolean对象。


3

布尔值基本上表示原始数据类型,布尔值表示参考数据类型。这个故事始于Java想成为纯粹的面向对象时,它提供了包装器类的概念,以取代原始数据类型的使用。

boolean b1;
Boolean b2;

b1而且b2不一样。



1

您可以使用布尔值/布尔值。简单是要走的路。如果您不需要特定的api(集合,流等),并且没有预见到需要它们,请使用它的原始版本(布尔值)。

  1. 使用基元可以保证您不会传递空值。
    您不会陷入这样的陷阱。下面的代码引发NullPointerException(来自:布尔值,条件运算符和自动装箱):

    public static void main(String[] args) throws Exception { Boolean b = true ? returnsNull() : false; // NPE on this line. System.out.println(b); } public static Boolean returnsNull() { return null; }

  2. 在需要对象时使用布尔值,例如:

    • 布尔流,
    • 可选的
    • 布尔值的集合
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.