[英]Boolean vs boolean in Java
在 Java 中有關於Integer
與int
討論。 前者的默認值為null
而后者的默認值為0
。 Boolean
與boolean
怎么樣?
我的應用程序中的變量可以有0
/ 1
值。 我想使用boolean
/ Boolean
而不想使用int
。 我可以改用Boolean
/ boolean
嗎?
是的,您可以使用Boolean
/ boolean
代替。
第一個是對象,第二個是原始類型。
第一個,您將獲得更多有用的方法。
考慮到內存費用,第二個很便宜第二個會為您節省更多內存,所以去吧
現在選擇你的方式。
Boolean
包裝了 boolean 原始類型。 在 JDK 5 及更高版本中,Oracle(或 Oracle 購買之前的 Sun)引入了autoboxing/unboxing ,這基本上允許您執行此操作
boolean result = Boolean.TRUE;
或
Boolean result = true;
基本上是編譯器所做的,
Boolean result = Boolean.valueOf(true);
所以,對於你的回答,是的。
我有點擴展提供的答案(因為到目前為止他們專注於他們的“自己的”/人工術語,專注於對特定語言進行編程,而不是在創建編程語言的場景背后照顧更大的圖景,一般來說,即當事情發生時就像類型安全與內存考慮因素有所不同):
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 行(bar)?1:0
上的 Java 代碼說明bar ( boolean ) 不能隱式轉換(強制轉換)為int 。 我提出這一點並不是為了說明 JVM 背后的實現細節,而是指出,就低級考慮(如內存大小)而言,人們確實必須更喜歡值而不是類型安全。 特別是如果該類型安全沒有像布爾類型那樣真正/完全使用,其中檢查以
如果值 \\in {0,1} 然后轉換為布爾類型,否則拋出異常。
只是為了說明 {0,1} < {-2^31, .. , 2^31 -1}。 好像有點矯枉過正吧? 類型安全在用戶定義的類型中確實很重要,而不是在原始類型的隱式轉換中(盡管最后一個包含在第一個中)。
字節不是類型或位
請注意,在內存中,{0,1} 范圍內的變量仍將至少占用一個字節或一個字(xbits 取決於寄存器的大小),除非特別注意(例如,在內存中很好地打包 - 8 "boolean"位轉換為 1 個字節 - 來回)。
通過更喜歡類型安全(例如將值放入/包裝到特定類型的盒子中)而不是額外的值打包(例如使用位移或算術),人們確實有效地選擇了編寫更少的代碼而不是獲得更多的內存。 (另一方面,人們總是可以定義一個自定義用戶類型,這將促進所有不值布爾值的轉換)。
關鍵字與類型
最后,您的問題是關於比較keyword與type 。 我認為通過使用/首選關鍵字(“標記”為 原語)而不是類型(使用另一個關鍵字class 的普通復合用戶可定義類)或換句話說,解釋為什么或如何准確地獲得性能很重要
boolean foo = true;
對比
Boolean foo = true;
第一個“事物”(類型)不能被擴展(子類化)並且不是沒有原因的。 有效地,原始類和包裝類的 Java 術語可以簡單地轉換為內聯值(一個 LITERAL 或一個常量,只要可以推斷替換,編譯器就會直接替換它,或者如果不是 - 仍然回退到包裝值)。
優化是由於微不足道的:
“更少的運行時轉換操作 => 更高的速度。”
這就是為什么當實際的類型推斷完成時,它可能(仍然)在必要時(或轉換/轉換成這樣)用所有類型信息實例化包裝類。
因此, boolean和Boolean之間的區別正是在編譯和運行時(有點遠,但幾乎就像instanceof與getClass() )。
最后,自動裝箱比基元慢
請注意,Java 可以進行自動裝箱這一事實只是一種“語法糖”。 它不會加速任何事情,只是讓您編寫更少的代碼。 就是這樣。 仍然執行類型信息容器的轉換和包裝。 出於性能原因,選擇算法將始終跳過創建具有類型信息的類實例以實現類型安全的額外內務處理。 缺乏類型安全是您為獲得性能而付出的代價。 對於具有布爾值表達式的代碼,類型安全(當您編寫較少的隱式代碼時)將是至關重要的,例如對於 if-then-else 流控制。
您可以使用布爾常量- Boolean.TRUE
和Boolean.FALSE
而不是0
和1
。 如果原始類型是您所追求的,您可以將變量創建為boolean
類型。 這樣您就不必創建新的Boolean
對象。
一個觀察:(雖然這可以被認為是副作用)
boolean是一個原始類型,可以說是或否。
Boolean是一個對象(它可以指是或否或“不知道”即空)
基本上 boolean 表示原始數據類型,其中 Boolean 表示參考數據類型。 這個故事開始於 Java 想要成為純粹的面向對象時,它提供了包裝類概念來取代原始數據類型的使用。
boolean b1;
Boolean b2;
b1
和b2
不一樣。
您可以使用布爾值/布爾值。 簡單是要走的路。 如果您不需要特定的 api(集合、流等)並且您沒有預見到您會需要它們 - 使用它的原始版本(布爾值)。
使用原語,您可以保證不會傳遞空值。
你不會落入這樣的陷阱。 下面的代碼拋出 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; }
當您需要一個對象時使用布爾值,例如:
Boolean
是線程安全的,因此您也可以考慮這個因素以及答案中列出的所有其他因素
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.