從 JDK 源碼角度看 Boolean

Java的Boolean類主要做用就是對基本類型boolean進行封裝,提供了一些處理boolean類型的方法,好比String類型和boolean類型的轉換。javascript

主要實現源碼以下:html

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。java

可是咱們說通常不推薦直接用構造函數來實例化Boolean對象,這是爲何?接着往下看,對於布爾值也就只有兩種狀態,咱們其實能夠僅僅用兩個對象就表示全部的布爾值,也就是說在Java的世界中只要全局存在兩個Boolean對象便可,實例化出多餘的Boolean對象仍然能正確表示布爾值,只是會浪費一些空間和影響時間性能。僅須要的兩個對象爲,數組

public static final Boolean TRUE = new Boolean(true);
  public static final Boolean FALSE = new Boolean(false);複製代碼

因此推薦的形式是Boolean.TRUEBoolean.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>oop

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。ui

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併發的原子性如何保證

相關文章
相關標籤/搜索