[Java原始碼]Boolean
因為業務發展關係,前段時間將一個風控平臺從Ruby語言遷移到了Java平臺,基於Spring進行了重構,寫了一段時間Java後,自己發現竟然還挺喜歡的(可能因為那段時間真的深深體會了 動態語言一時爽,重構火葬場 的玩笑)。所以後續決定閱讀部分原始碼進行深入提升Java水平,網上搜索了一番,看到了很多的推薦,例如Spring
框架的原始碼之類的,還有一些其他的開源元件專案,但是後面想想還是先從Java基礎入手吧,於是就有了這篇文章,從最簡單的Boolean開始。
原始碼基於 jdk1.8.0_181.jdk 版本。水平有限,第一次看相關程式碼,也第一次寫?如有建議和意見,歡迎聯絡指出。
概要
Java的Boolean
boolean
基本資料型別的封裝,有著一個欄位存放對應的boolean
資料值,提供了許多方法方便對boolean
進行操作。
類定義
public final class Boolean implements java.io.Serializable,Comparable<Boolean>
複製程式碼
因為帶有final
關鍵字,也就是不可繼承,另外實現了Serializable
和Comparable
介面,也就是可以進行序列化和比較的。
屬性
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
複製程式碼
TRUE
和FALSE
定義了兩個靜態常量,代表著boolean
中的true
和false
。
@SuppressWarnings("unchecked")
public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");
複製程式碼
獲取類資訊,Boolean.TYPE == boolean.class
兩者是等價的。
private final boolean value;
複製程式碼
Boolean
因為是boolean
的包裝類,所以這裡就是包含了對應的boolean基本型別的變數
private static final long serialVersionUID = -3665804199014368530L;
複製程式碼
方法
構造方法
public Boolean(boolean value) {
this.value = value;
}
public Boolean(String s) {
this(parseBoolean(s));
}
複製程式碼
存在兩個構造方法,一個是傳入boolean型別值,一個是傳入字串解析,而對應的解析方法如下:
public static boolean parseBoolean(String s) {
return ((s != null) && s.equalsIgnoreCase("true"));
}
複製程式碼
這裡就很直白的告訴了你,只有true
(忽略大小寫)格式的字串才會返回true
,其餘的都為false
。這裡自己因此還踩過坑,一直以為字串存在時就是真值,還是和Ruby不一樣的。
valueOf 方法
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
public static Boolean valueOf(String s) {
return parseBoolean(s) ? TRUE : FALSE;
}
複製程式碼
我們通過Boolean b = new Boolean(true);
時會獲得一個新的例項物件,當你並不需要這個新例項而只要對應的值時,就應該採用這裡的靜態方法,直接返回了上面定義的靜態變數,節省了一點記憶體又避免了建立一個新例項的時間開銷。
booleanValue 方法
public boolean booleanValue() {
return value;
}
複製程式碼
獲取對應的boolean型別值。
toString 方法
public static String toString(boolean b) {
return b ? "true" : "false";
}
public String toString() {
return value ? "true" : "false";
}
複製程式碼
返回對應布林值的String物件。如果為true
則返回"true"字串,否則就是"false"。
hashcode 方法
@Override
public int hashCode() {
return Boolean.hashCode(value);
}
public static int hashCode(boolean value) {
return value ? 1231 : 1237;
}
複製程式碼
其中重寫了hashcode
方法,返回值呼叫了靜態方法hashcode
,而靜態方法返回值:當true
時返回1231,false
返回1237。這裡很有意思的是這兩個固定的數字,很好奇為什麼是這兩個值,所以網上搜索了下,有兩篇回答可以參考一下。
大致意思是,主要這兩個是較大的質數(實際上其他較大的質數也可以),至於較大質數的原因是可以有效減少Hash碰撞衝突的發生。而Boolean是一個很常用的物件,會經常在其他裡面使用,這麼做有助於提升效率。
equals 方法
public boolean equals(Object obj) {
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}
複製程式碼
首先判斷傳入的obj
是不是Boolean
的例項,然後比較兩者的值是否相等。從這裡可以發現,如果我們習慣於在判斷前增加if (null == obj)
的邏輯,其實在這裡是可以忽略的,因為null
肯定不是Boolean
的例項,會直接返回false
。
getBoolean 方法
public static boolean getBoolean(String name) {
boolean result = false;
try {
result = parseBoolean(System.getProperty(name));
} catch (IllegalArgumentException | NullPointerException e) {
}
return result;
}
複製程式碼
從程式碼上看,這個方法並不是將輸入字串轉換成boolean
型別的方法。而是當且僅當 系統屬性 中存在著對應名稱的屬性,且它的值為“true”(忽略大小寫)時,返回true
型別,否則返回false
。
compare 方法
public int compareTo(Boolean b) {
return compare(this.value,b.value);
}
public static int compare(boolean x,boolean y) {
return (x == y) ? 0 : (x ? 1 : -1);
}
複製程式碼
比較兩個Boolean例項物件或者boolean型別值,當相等時,返回0;否則根據第一個值進行判斷,第一個值為true
時返回1,否則返回-1。
logical 比較方法
public static boolean logicalAnd(boolean a,boolean b) {
return a && b;
}
public static boolean logicalOr(boolean a,boolean b) {
return a || b;
}
public static boolean logicalXor(boolean a,boolean b) {
return a ^ b;
}
複製程式碼
提供了三個靜態方法,對於兩個boolean
型別值進行與、或、異或操作,返回對應的判斷結果值。
boolean型別
在看程式碼的過程中,想知道boolean到底是個啥東西,然後去看了下 oracle 的官方檔案,突然學到了一點小知識,順帶記錄一下。
在Java的八種基本資料型別中,除了boolean
其它7種都有明確的位元組數長度,只有boolean
沒有給出具體的位元組數長度定義,詳細的介紹如下:
boolean: The
boolean
data type has only two possible values:true
andfalse
. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information,but its "size" isn't something that's precisely defined.
boolean
只存在true
和false
兩個值,這個資料型別也是用於跟蹤真/假條件的簡單標誌。這個資料型別代表了1bit的資訊,但是它的大小並沒有明確的定義。由此搜尋了一下,發現具體的應該是由Java虛擬機器器規範定義的。官方的檔案 Java Virtual Machine Specification 有這個相關的說明,boolean
型別值會被編譯使用int
型別進行替換,也就是4位元組的大小;而boolean
型別陣列,jvm並不是直接支援的,而是通過byte[]
實現,其中也就是佔用1位元組。具體的說明可以檢視提供的原文連結,也是非常有意思的資訊。
總結
整體的原始碼是很簡單的,但是這次檢視原始碼的過程中也學到了很多的東西,平時一些可能完全不會關注的點,在這次過程中也都學習到了,例如有些情況下應該使用Boolean.valueOf(true)
替換new Boolean(true)
,hashCode
的值,boolean
的相關檔案定義等等,魔鬼藏在細節裡,繼續加油。
最後
對應部落格地址:blog.renyijiu.com/post/java原始碼…