由於業務發展關係,前段時間將一個風控平臺從Ruby語言遷移到了Java平臺,基於Spring進行了重構,寫了一段時間Java後,本身發現居然還挺喜歡的(可能由於那段時間真的深深體會了 動態語言一時爽,重構火葬場 的玩笑)。因此後續決定閱讀部分源碼進行深刻提高Java水平,網上搜索了一番,看到了不少的推薦,例如Spring
框架的源碼之類的,還有一些其餘的開源組件項目,可是後面想一想仍是先從Java基礎入手吧,因而就有了這篇文章,從最簡單的Boolean開始。html
源代碼基於 jdk1.8.0_181.jdk 版本。水平有限,第一次看相關代碼,也第一次寫😂若有建議和意見,歡迎聯繫指出。java
Java的Boolean
對象是對boolean
基本數據類型的封裝,有着一個字段存放對應的boolean
數據值,提供了許多方法方便對boolean
進行操做。數組
public final class Boolean implements java.io.Serializable, Comparable<Boolean> 複製代碼
由於帶有final
關鍵字,也就是不可繼承,另外實現了Serializable
和Comparable
接口,也就是能夠進行序列化和比較的。oracle
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
二者是等價的。jvm
private final boolean value;
複製代碼
Boolean
由於是boolean
的包裝類,因此這裏就是包含了對應的boolean基本類型的變量ide
private static final long serialVersionUID = -3665804199014368530L;
複製代碼
public Boolean(boolean value) {
this.value = value;
}
public Boolean(String s) {
this(parseBoolean(s));
}
複製代碼
存在兩個構造方法,一個是傳入boolean類型值,一個是傳入字符串解析,而對應的解析方法以下:post
public static boolean parseBoolean(String s) {
return ((s != null) && s.equalsIgnoreCase("true"));
}
複製代碼
這裏就很直白的告訴了你,只有true
(忽略大小寫)格式的字符串纔會返回true
,其他的都爲false
。這裏本身所以還踩過坑,一直覺得字符串存在時就是真值,仍是和Ruby不同的。學習
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);
時會得到一個新的實例對象,當你並不須要這個新實例而只要對應的值時,就應該採用這裏的靜態方法,直接返回了上面定義的靜態變量,節省了一點內存又避免了建立一個新實例的時間開銷。this
public boolean booleanValue() {
return value;
}
複製代碼
獲取對應的boolean類型值。
public static String toString(boolean b) {
return b ? "true" : "false";
}
public String toString() {
return value ? "true" : "false";
}
複製代碼
返回對應布爾值的String對象。若是爲true
則返回"true"字符串,不然就是"false"。
@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是一個很經常使用的對象,會常常在其餘裏面使用,這麼作有助於提高效率。
public boolean equals(Object obj) {
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}
複製代碼
首先判斷傳入的obj
是否是Boolean
的實例,而後比較二者的值是否相等。從這裏能夠發現,若是咱們習慣於在判斷前增長if (null == obj)
的邏輯,其實在這裏是能夠忽略的,由於null
確定不是Boolean
的實例,會直接返回false
。
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
。
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。
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究竟是個啥東西,而後去看了下 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
的相關文檔定義等等,魔鬼藏在細節裏,繼續加油。