Java的Boolean類主要作用就是對基本型別boolean進行封裝,提供了一些處理boolean型別的方法,比如String型別和boolean型別的轉換。
主要實現原始碼如下:
public final class Boolean implements java.io.Serializable, Comparable<Boolean> {
private final boolean value;
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");
public Boolean(boolean value) {
this.value = value;
}
public Boolean(String s) {
this(parseBoolean(s));
}
public static boolean parseBoolean(String s) {
return ((s != null) && s.equalsIgnoreCase("true"));
}
public boolean booleanValue() {
return value;
}
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
public static Boolean valueOf(String s) {
return parseBoolean(s) ? TRUE : FALSE;
}
public static String toString(boolean b) {
return b ? "true" : "false";
}
public String toString() {
return value ? "true" : "false";
}
public int hashCode() {
return Boolean.hashCode(value);
}
public static int hashCode(boolean value) {
return value ? 1231 : 1237;
}
public boolean equals(Object obj) {
if (obj instanceof Boolean) {
return value == ((Boolean) obj).booleanValue();
}
return 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);
}
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的封裝,那必然要有一個變數來儲存,即value,而且它被宣告為final,表明它是不可變的。兩種建構函式可分別傳入boolean和String型別,對於String型別會進行”to boolean”解析,即當傳入的字串忽略大小寫等於”true”時判斷為true,否則為false。
但是我們說一般不推薦直接用建構函式來例項化Boolean物件,這是為什麼?接著往下看,對於布林值也就只有兩種狀態,我們其實可以僅僅用兩個物件就表示所有的布林值,也就是說在Java的世界中只要全域性存在兩個Boolean物件即可,例項化出多餘的Boolean物件仍然能正確表示布林值,只是會浪費一些空間和影響時間效能。僅需要的兩個物件為,
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);複製程式碼
所以推薦的形式是Boolean.TRUE
或Boolean.valueOf(true)
或Boolean.valueOf("true")
,避免生成不必要的物件。
接著再看看Boolean的TYPE屬性,它toString的值其實是boolean
。
public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");複製程式碼
看看怎麼來的。Class的getPrimitiveClass
是一個native方法,在Class.c
中有個Java_java_lang_Class_getPrimitiveClass
方法與之對應,所以JVM層面會通過JVM_FindPrimitiveClass
函式會根據”boolean”字串獲得jclass,最終到Java層則為Class<Boolean>
。
Java_java_lang_Class_getPrimitiveClass(JNIEnv *env,
jclass cls,
jstring name)
{
const char *utfName;
jclass result;
if (name == NULL) {
JNU_ThrowNullPointerException(env, 0);
return NULL;
}
utfName = (*env)->GetStringUTFChars(env, name, 0);
if (utfName == 0)
return NULL;
result = JVM_FindPrimitiveClass(env, utfName);
(*env)->ReleaseStringUTFChars(env, name, utfName);
return result;
}複製程式碼
當TYPE
執行toString時,邏輯如下,則其實是getName
函式決定其值,getName
通過native方法getName0
從JVM層獲取名稱,
public String toString() {
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ getName();
}複製程式碼
getName0
根據一個陣列獲得對應的名稱,JVM根據Java層的Class可得到對應型別的陣列下標,比如這裡下標為4,則名稱為”boolean”。
const char* type2name_tab[T_CONFLICT+1] = {
NULL, NULL, NULL, NULL,
"boolean",
"char",
"float",
"double",
"byte",
"short",
"int",
"long",
"object",
"array",
"void",
"*address*",
"*narrowoop*",
"*conflict*"
};複製程式碼
往下繼續看HashCode,實現邏輯如下,即true返回1231而false返回1237。
public static int hashCode(boolean value) {
return value ? 1231 : 1237;
}複製程式碼
equals
方法就是先判斷是不是從Boolean例項化出來的,然後再繼續比較是不是相等。
實現Comparable<Boolean>
介面是為了方便在集合中進行比較,它需要實現的方法為compareTo
。
此外,還提供了logicalAnd、logicalOr和logicalXor用於實現三種邏輯運算。
以下是廣告和相關閱讀
========廣告時間========
鄙人的新書《Tomcat核心設計剖析》已經在京東銷售了,有需要的朋友可以到 item.jd.com/12185360.ht… 進行預定。感謝各位朋友。
=========================
相關閱讀:
談談Java基礎資料型別
從JDK原始碼角度看併發鎖的優化
從JDK原始碼角度看執行緒的阻塞和喚醒
從JDK原始碼角度看併發競爭的超時
從JDK原始碼角度看java併發執行緒的中斷
從JDK原始碼角度看Java併發的公平性
從JDK原始碼角度看java併發的原子性如何保證