在Java中有关于Integer和int的讨论。前者的默认值为null,而后者的默认值为0。布尔和布尔呢?
我的应用程序中的变量可以有0/1的值。我想使用布尔/布尔,而不喜欢使用int。我可以用布尔/布尔代替吗?
在Java中有关于Integer和int的讨论。前者的默认值为null,而后者的默认值为0。布尔和布尔呢?
我的应用程序中的变量可以有0/1的值。我想使用布尔/布尔,而不喜欢使用int。我可以用布尔/布尔代替吗?
当前回答
布尔表示基本数据类型,其中布尔表示引用数据类型。这个故事开始于Java想要成为纯粹面向对象的时候,它提供了包装类的概念来克服原始数据类型的使用。
boolean b1;
Boolean b2;
B1和b2不一样。
其他回答
是的,你可以用布尔/布尔来代替。
第一个是对象,第二个是基本类型。
第一个,你会得到更多有用的方法。 考虑到内存消耗,第二种方法很便宜。第二种方法会节省你更多的内存,所以试试吧
现在选择你的道路。
一个观察结果:(尽管这可以被认为是副作用)
布尔是一个原语,可以表示“是”或“否”。
Boolean是一个对象(它可以指yes或no或'don't know'即null)
你可以使用Boolean / Boolean。简单才是正确之道。 如果你不需要特定的api(集合,流等),并且你没有预见到你会需要它们-使用它的原始版本(布尔)。
With primitives you guarantee that you will not pass null values. You will not fall in traps like this. The code below throws NullPointerException (from: Booleans, conditional operators and autoboxing): 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; } Use Boolean when you need an object, eg: Stream of Booleans, Optional Collections of Booleans
我有点扩展提供的答案(因为到目前为止,他们专注于“自己的”/人工术语,专注于编程一种特定的语言,而不是关心创建编程语言的场景背后的更大的画面,一般来说,即当类型安全与内存考虑因素产生差异时):
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
Java代码在第三行(酒吧)?1:0说明bar (boolean)不能隐式转换(强制转换)为int型。我提出这一点并不是为了说明JVM背后的实现细节,而是为了指出在低级别的考虑(如内存大小)方面,人们确实必须优先考虑值而不是类型安全。特别是在布尔类型中,类型安全没有真正/完全使用,在布尔类型中,以的形式进行检查
如果值\在{0,1}中,则转换为布尔类型,否则抛出异常。
只要声明{0,1}< {-2^31,.., 2^31 -1}。听起来有点过头了,对吧?类型安全在用户定义的类型中真正重要,而在原语的隐式强制转换中并不重要(尽管last包含在first中)。
字节不是类型或位
请注意,在内存中,你的变量{0,1}仍然会占用至少一个字节或一个字(xbits取决于寄存器的大小),除非特别处理(例如,在内存中很好地打包- 8个“布尔”位到一个字节-来回)。
通过选择类型安全(例如将值放入/包装到特定类型的盒子中)而不是额外的值包装(例如使用位移位或算术),人们确实有效地选择了写更少的代码而不是获得更多的内存。(另一方面,总是可以定义一个自定义的用户类型,这将有助于所有不大于布尔值的转换)。
关键字与类型
最后,你的问题是关于比较关键字和类型。我相信,解释为什么或如何通过使用/偏好关键字(“标记”为原始)而不是类型(使用另一个关键字类的普通组合用户可定义类)来获得性能是很重要的。 或者换句话说
boolean foo = true;
vs.
Boolean foo = true;
第一个“东西”(类型)不能被扩展(子类化),而且不是没有原因的。实际上,原语类和包装类的Java术语可以简单地转换为内联值(一个LITERAL或一个常量,在可能推断出替换时被编译器直接替换,如果不能——仍然返回到包装值)。
实现优化的原因是:
“更少的运行时强制转换操作=>更快的速度。”
这就是为什么当实际的类型推断完成时,如果需要(或转换/强制转换为此类信息),它可能(仍然)以封装类的实例化结束。
因此,布尔和布尔之间的区别恰恰是在编译和运行时(有点远,但几乎是instanceof vs. getClass())。
最后,自动装箱比原语慢
Note the fact that Java can do autoboxing is just a "syntactic sugar". It does not speed up anything, just allows you to write less code. That's it. Casting and wrapping into type information container is still performed. For performance reasons choose arithmetics which will always skip extra housekeeping of creating class instances with type information to implement type safety. Lack of type safety is the price you pay to gain performance. For code with boolean-valued expressions type safety (when you write less and hence implicit code) would be critical e.g. for if-then-else flow controls.
你可以使用布尔常数-布尔。TRUE和布尔值。FALSE而不是0和1。你可以创建你的变量类型布尔,如果原始是什么,你是之后。这样你就不必创建新的布尔对象了。