Java 中的布尔值与布尔值
有关于 Java 中的 Integer
与 int
的讨论。前者的默认值为null
,而后者的默认值为0
。 Boolean
与 boolean
怎么样?
我的应用程序中的变量可以有 0
/1
值。我想使用 boolean
/Boolean
并且不喜欢使用 int
。我可以使用 Boolean
/boolean
代替吗?
There are discussions around Integer
vs int
in Java. The default value of the former is null
while in the latter it's 0
. How about Boolean
vs boolean
?
A variable in my application can have 0
/1
values. I would like to use boolean
/Boolean
and prefer not to use int
. Can I use Boolean
/boolean
instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
是您可以使用
Boolean
/boolean
代替。第一个是对象,第二个是原始类型。
在第一个中,您将获得更多有用的方法。
考虑到内存消耗,第二个很便宜 第二个会节省你更多的内存,所以就用它
现在选择您的方式。
Yes you can use
Boolean
/boolean
instead.First one is Object and second one is primitive type.
On first one, you will get more methods which will be useful.
Second one is cheap considering memory expense The second will save you a lot more memory, so go for it
Now choose your way.
Boolean
包装布尔原始类型。在 JDK 5 及更高版本中,Oracle(或 Oracle 收购之前的 Sun)引入了 自动装箱/拆箱,它本质上允许您执行此操作或
编译器本质上执行此操作,
因此,对于您的答案,是的。
Boolean
wraps the boolean primitive type. In JDK 5 and upwards, Oracle (or Sun before Oracle bought them) introduced autoboxing/unboxing, which essentially allows you to do thisor
Which essentially the compiler does,
So, for your answer, it's YES.
我对提供的答案进行了一些扩展(因为到目前为止,他们专注于自己的“自己的”/人工术语,专注于对特定语言进行编程,而不是关注创建编程语言幕后的大局,一般来说,即当类型安全与内存考虑等因素产生差异时):
int 不是布尔值
考虑
在第 3 行输出
Java 代码
(bar)?1:0< /code> 说明 bar(boolean)无法隐式转换(强制转换)为 int。我提出这一点并不是为了说明 JVM 背后的实现细节,而是为了指出,就低级考虑(如内存大小)而言,人们确实必须更喜欢值而不是类型安全。特别是如果类型安全没有像布尔类型那样真正/完全使用,其中检查以以下形式完成
所有这些只是为了说明 {0,1} < {-2^31, .., 2^31 -1}。看起来有点矫枉过正,对吧?类型安全在用户定义的类型中确实很重要,而不是在基元的隐式转换中(尽管最后一个包含在第一个中)。
字节不是类型或位
请注意,在内存中,{0,1}范围内的变量仍将至少占用一个字节或一个字(x位取决于寄存器的大小),除非特别采取照顾(例如在内存中很好地打包 - 8 个“布尔”位到 1 个字节 - 来回)。
通过优先选择类型安全(如将值放入/包装到特定类型的框中)而不是额外的值打包(例如使用移位或算术),人们确实有效地选择编写更少的代码而不是获得更多的内存。 (另一方面,人们总是可以定义自定义用户类型,这将促进所有不值布尔值的转换)。
关键字与类型
最后,您的问题是关于比较关键字与类型。我认为解释为什么或如何通过使用/首选关键字(“标记”为原始) 类型(使用另一个关键字 class 的普通复合用户可定义类)
或者换句话说,
第
一个“事物”(类型)不能被扩展(子类化),而且不是没有原因的。实际上,原始和包装类的Java术语可以简单地转换为内联值(一个LITERAL或一个常量,只要它被编译器直接替换)可以推断替换,或者如果没有 - 仍然回退到包装值)。
优化是由于微不足道而实现的:
这就是为什么当实际类型推断完成时,如果需要的话,它可能(仍然)最终用所有类型信息实例化包装类(或转换/转换为此类)。
因此,boolean和Boolean之间的区别正是在编译和运行时(有点远,但几乎一样) instanceof 与 getClass())。
最后,自动装箱比原语慢
请注意,Java 可以自动装箱只是一个“语法糖”。它不会加快任何速度,只是允许您编写更少的代码。就是这样。仍然会执行类型信息容器的转换和包装。出于性能原因,选择始终会跳过使用类型信息创建类实例的额外内务处理以实现类型安全的算法。缺乏类型安全是您为获得性能而付出的代价。对于具有布尔值表达式的代码,类型安全性(当您编写较少的代码并因此隐式代码时)至关重要,例如对于 if-then-else 流程控制。
I am a bit extending provided answers (since so far they concentrate on their "own"/artificial terminology focusing on programming a particular language instead of taking care of the bigger picture behind the scene of creating the programming languages, in general, i.e. when things like type-safety vs. memory considerations make the difference):
int is not boolean
Consider
with output
Java code on 3rd line
(bar)?1:0
illustrates that bar (boolean) cannot be implicitly converted (casted) into an int. I am bringing this up not to illustrate the details of implementation behind JVM, but to point out that in terms of low level considerations (as memory size) one does have to prefer values over type safety. Especially if that type safety is not truly/fully used as in boolean types where checks are done in form ofAll just to state that {0,1} < {-2^31, .. , 2^31 -1}. Seems like an overkill, right? Type safety is truly important in user defined types, not in implicit casting of primitives (although last are included in the first).
Bytes are not types or bits
Note that in memory your variable from range of {0,1} will still occupy at least a byte or a word (xbits depending on the size of the register) unless specially taken care of (e.g. packed nicely in memory - 8 "boolean" bits into 1 byte - back and forth).
By preferring type safety (as in putting/wrapping value into a box of a particular type) over extra value packing (e.g. using bit shifts or arithmetic), one does effectively chooses writing less code over gaining more memory. (On the other hand one can always define a custom user type which will facilitate all the conversion not worth than Boolean).
keyword vs. type
Finally, your question is about comparing keyword vs. type. I believe it is important to explain why or how exactly you will get performance by using/preferring keywords ("marked" as primitive) over types (normal composite user-definable classes using another keyword class)
or in other words
vs.
The first "thing" (type) can not be extended (subclassed) and not without a reason. Effectively Java terminology of primitive and wrapping classes can be simply translated into inline value (a LITERAL or a constant that gets directly substituted by compiler whenever it is possible to infer the substitution or if not - still fallback into wrapping the value).
Optimization is achieved due to trivial:
That is why when the actual type inference is done it may (still) end up in instantiating of wrapping class with all the type information if necessary (or converting/casting into such).
So, the difference between boolean and Boolean is exactly in Compilation and Runtime (a bit far going but almost as instanceof vs. getClass()).
Finally, autoboxing is slower than primitives
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.
您可以使用布尔常量 -
Boolean.TRUE
和Boolean.FALSE
而不是0
和1
。如果您想要的是原始类型,您可以创建boolean
类型的变量。这样您就不必创建新的Boolean
对象。You can use the Boolean constants -
Boolean.TRUE
andBoolean.FALSE
instead of0
and1
. You can create your variable as of typeboolean
if primitive is what you are after. This way you won't have to create newBoolean
objects.一个观察:(尽管这可以被认为是副作用)
作为原语的 boolean 可以说是或否。
Boolean 是一个对象(它可以指的是或否或“不知道”,即 null)
One observation: (though this can be thought of side effect)
boolean being a primitive can either say yes or no.
Boolean is an object (it can refer to either yes or no or 'don't know' i.e. null)
基本上,布尔值表示原始数据类型,其中布尔值表示引用数据类型。这个故事是从Java想要成为纯粹面向对象的时候开始的,它提供了包装类概念来克服原始数据类型的使用。
b1
和b2
不同。Basically boolean represent a primitive data type where Boolean represent a reference data type. this story is started when Java want to become purely object oriented it's provided wrapper class concept to over come to use of primitive data type.
b1
andb2
are not same.您可以使用布尔值/布尔值。简单是必经之路。
如果您不需要特定的 api(集合、流等)并且您没有预见到您将需要它们 - 使用它的原始版本(布尔值)。
使用原语,您可以保证不会传递空值。
你不会陷入这样的陷阱。下面的代码抛出 NullPointerException (来自:布尔值、条件运算符和自动装箱):
public static void main(String[] args) 抛出异常 {
布尔值 b = true ?返回Null():假; // 此行上的 NPE。
System.out.println(b);
}
公共静态布尔返回Null(){
返回空值;
}
当你需要一个对象时使用布尔值,例如:
You can use Boolean / boolean. Simplicity is the way to go.
If you do not need specific api (Collections, Streams, etc.) and you are not foreseeing that you will need them - use primitive version of it (boolean).
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:
Boolean
是线程安全的,因此您可以考虑这个因素以及答案中列出的所有其他因素Boolean
is threadsafe, so you can consider this factor as well along with all other listed in answers