Boolean原始碼解剖學

朱季謙 發表於 2020-08-01

一.類繼承

Boolean的原始碼類定義部分如下:

  1 public final class Boolean implements java.io.Serializable,
  2                                       Comparable<Boolean>

在IDEA生成其類繼承圖:

clipboard

根據以上資訊可以得知:

1.Boolean類實現了java.io.Serializable介面,眾所周知,這是實現物件序列化的功能。

2.Boolean類實現了Comparable<Boolean>介面。

那麼問題來了?

這個Comparable<Boolean>介面是什麼東西呢?

看起來是否很眼熟,是否曾在瀚海程式碼量裡偶然一瞥過?

若你在字串裡用過str.compareTo(str2)來做過比較排序話,那你一定多少有點印象,其實Java中的所有compareTo方法都來源於一個共同的祖先,即Comparable介面。

Boolean類同樣繼承是這個Comparable介面,它的原始碼很簡單,就只定義了一個方法:

  1 public interface Comparable<T> {
  2     public int compareTo(T o);
  3 }

繼承該介面的類,都可通過compareTo方法來對類物件進行排序。該方法將物件與指定物件的順序做比較,若物件大於、等於或小於指定物件,將分別返回1,0,-1,

推而論之,你也可以由此而明白str.compareTo(str2)底層的繼承原理了。


二.類結構

Boolean原始碼定義了以下的欄位與方法,下面將逐一學習分析:

clipboard

Boolean類包含以下屬性:

  1 public static final Boolean TRUE = new Boolean(true);
  2 
  3 public static final Boolean FALSE = new Boolean(false);
  4 
  5 
  6 @SuppressWarnings("unchecked")
  7 public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");
  8 
  9 
 10 private final boolean value;
 11 
 12 //用於Java序列化機制,在序列化與反序列過程中,用於判斷反序列化檔案與該類是否同一版本,若同可反序列化成功。
 13 private static final long serialVersionUID = -3665804199014368530L;

說明:

1.TRUE與FALSE是Boolean提供的兩個靜態常量,在用到true或者false時,可直接用這兩個常量,無需再耗費資源來建立類似new Boolean(true)這樣的新例項;

2.TYPE 基本型別 boolean 的 Class 物件,可用於類反射;

3.value是一個final 定義的私有變數,即

  1 public Boolean(boolean value) {
  2     this.value = value;
  3 }
  1 public Boolean(String s) {
  2     this(parseBoolean(s));
  3 }

第一個比較好理解,那第二個的parseBoolean(s)是什麼方法呢?

跟蹤進去看,在該方法裡,會將String字串做比較,只有s為“true”時傳進去,才會返回一個boolean值。

  1 public static boolean parseBoolean(String s) {
  2     return ((s != null) && s.equalsIgnoreCase("true"));
  3 }

Boolean的hash值是比較有意思:

  1 @Override
  2 public int hashCode() {
  3     return Boolean.hashCode(value);
  4 }

當true時,得到的是1231,當false,得到的是1237。

  1 public static int hashCode(boolean value) {
  2     return value ? 1231 : 1237;
  3 }

那麼,問題來了,為啥Boolean的hash值為什麼選擇這兩個數字呢?

主要原因是,1231與1237是比較大的素數,而選擇素數是為了在雜湊桶中最好地分配資料,其實Boolean也可以選擇其他素數作為其雜湊值,據說這純粹是作者的個人喜好。

有個有趣的地方是,當

true: 1231 => 1 + 2 + 3 + 1 = 7;

7-是歐洲傳統中的幸運數字;

false: 1237 => 1 + 2 + 3 + 7 = 13;

13則是不吉祥的數字;