简体   繁体   English

Java 中的布尔值与布尔值

[英]Boolean vs boolean in Java

There are discussions around Integer vs int in Java.在 Java 中有关于Integerint讨论。 The default value of the former is null while in the latter it's 0 .前者的默认值为null而后者的默认值为0 How about Boolean vs boolean ? Booleanboolean怎么样?

A variable in my application can have 0 / 1 values.我的应用程序中的变量可以有0 / 1值。 I would like to use boolean / Boolean and prefer not to use int .我想使用boolean / Boolean而不想使用int Can I use Boolean / boolean instead?我可以改用Boolean / boolean吗?

Yes you can use Boolean / boolean instead.是的,您可以使用Boolean / boolean代替。

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 wraps the boolean primitive type. Boolean包装了 boolean 原始类型。 In JDK 5 and upwards, Oracle (or Sun before Oracle bought them) introduced autoboxing/unboxing , which essentially allows you to do this在 JDK 5 及更高版本中,Oracle(或 Oracle 购买之前的 Sun)引入了autoboxing/unboxing ,这基本上允许您执行此操作

boolean result = Boolean.TRUE;

or

Boolean result = true; 

Which essentially the compiler does,基本上是编译器所做的,

Boolean result = Boolean.valueOf(true);

So, for your answer, it's YES.所以,对于你的回答,是的。

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, ie when things like type-safety vs. memory considerations make the difference):我有点扩展提供的答案(因为到目前为止他们专注于他们的“自己的”/人工术语,专注于对特定语言进行编程,而不是在创建编程语言的场景背后照顾更大的图景,一般来说,即当事情发生时就像类型安全与内存考虑因素有所不同):

int is not boolean int 不是布尔值

Consider考虑

    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);

with output带输出

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

Java code on 3rd line (bar)?1:0 illustrates that bar ( boolean ) cannot be implicitly converted (casted) into an int .第 3 行(bar)?1:0上的 Java 代码说明bar ( boolean ) 不能隐式转换(强制转换)为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.我提出这一点并不是为了说明 JVM 背后的实现细节,而是指出,就低级考虑(如内存大小)而言,人们确实必须更喜欢值而不是类型安全。 Especially if that type safety is not truly/fully used as in boolean types where checks are done in form of特别是如果该类型安全没有像布尔类型那样真正/完全使用,其中检查以

if value \\in {0,1} then cast to boolean type, otherwise throw an exception.如果值 \\in {0,1} 然后转换为布尔类型,否则抛出异常。

All just to state that {0,1} < {-2^31, .. , 2^31 -1}.只是为了说明 {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 (eg packed nicely in memory - 8 "boolean" bits into 1 byte - back and forth).请注意,在内存中,{0,1} 范围内的变量仍将至少占用一个字节或一个字(xbits 取决于寄存器的大小),除非特别注意(例如,在内存中很好地打包 - 8 "boolean"位转换为 1 个字节 - 来回)。

By preferring type safety (as in putting/wrapping value into a box of a particular type) over extra value packing (eg 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 .最后,您的问题是关于比较keywordtype 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我认为通过使用/首选关键字(“标记”为 原语)而不是类型(使用另一个关键字class 的普通复合用户可定义类)或换句话说,解释为什么或如何准确地获得性能很重要

boolean foo = true;

vs.对比

Boolean foo = true;

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).有效地,原始类和包装类的 Java 术语可以简单地转换为内联值(一个 LITERAL 或一个常量,只要可以推断替换,编译器就会直接替换它,或者如果不是 - 仍然回退到包装值)。

Optimization is achieved due to trivial:优化是由于微不足道的:

"Less runtime casting operations => more speed." “更少的运行时转换操作 => 更高的速度。”

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() ).因此, booleanBoolean之间的区别正是在编译运行时(有点远,但几乎就像instanceofgetClass() )。

Finally, autoboxing is slower than primitives最后,自动装箱比基元慢

Note the fact that Java can do autoboxing is just a "syntactic sugar".请注意,Java 可以进行自动装箱这一事实只是一种“语法糖”。 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 eg for if-then-else flow controls.对于具有布尔值表达式的代码,类型安全(当您编写较少的隐式代码时)将是至关重要的,例如对于 if-then-else 流控制。

You can use the Boolean constants - Boolean.TRUE and Boolean.FALSE instead of 0 and 1 .您可以使用布尔常量- Boolean.TRUEBoolean.FALSE而不是01 You can create your variable as of type boolean if primitive is what you are after.如果原始类型是您所追求的,您可以将变量创建为boolean类型。 This way you won't have to create new Boolean objects.这样您就不必创建新的Boolean对象。

One observation: (though this can be thought of side effect)一个观察:(虽然这可以被认为是副作用)

boolean being a primitive can either say yes or no. boolean是一个原始类型,可以说是或否。

Boolean is an object (it can refer to either yes or no or 'don't know' ie null) Boolean是一个对象(它可以指是或否或“不知道”即空)

Basically boolean represent a primitive data type where Boolean represent a reference data type.基本上 boolean 表示原始数据类型,其中 Boolean 表示参考数据类型。 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.这个故事开始于 Java 想要成为纯粹的面向对象时,它提供了包装类概念来取代原始数据类型的使用。

boolean b1;
Boolean b2;

b1 and b2 are not same. b1b2不一样。

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).如果您不需要特定的 api(集合、流等)并且您没有预见到您会需要它们 - 使用它的原始版本(布尔值)。

  1. 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 ):下面的代码抛出 NullPointerException(来自: Booleans、conditional operators 和 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; }

  2. Use Boolean when you need an object, eg:当您需要一个对象时使用布尔值,例如:

    • Stream of Booleans,布尔值流,
    • Optional可选
    • Collections of Booleans布尔值的集合

Boolean是线程安全的,因此您也可以考虑这个因素以及答案中列出的所有其他因素

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM