Objects類源碼筆記

Objects類是一個提供對象基礎(chǔ)操作的工具類,其提供的方法包括null-safe或tolerant-safe的對象hashcode計算力麸,toString和比較等挚冤。
所在路徑:\java\util\Objects.java

Objects類結(jié)構(gòu)

一减噪、構(gòu)造器

Objects類被final修飾致扯,不能被繼承。其構(gòu)造方法直接拋出一個Error像街,不允許被實例化黎棠。

private Objects() {
    throw new AssertionError("No java.util.Objects instances for you!");
}

二、equals()

在判斷值相等時可以容忍對象為null的情況镰绎。

public static boolean equals(Object a, Object b) {
    return (a == b) || (a != null && a.equals(b));
}

相比之下脓斩,Object類的equals()方法在自身為null時會拋出nullPointerException。
Object類的equals()方法:

public boolean equals(Object obj) {
    return (this == obj);
}

三跟狱、deepEquals()

deepEquals()方法實現(xiàn)了兩個對象是否相等的深度判斷俭厚,如果對象是一個數(shù)組,則對數(shù)組的每一個元素進行比較驶臊;如果數(shù)組中的每一個元素仍然是object挪挤,則對其進行遞歸的比較。

被比較的任意一個對象為null時返回false而不是繼續(xù)判斷关翎,因此在兩對象都為null時只能得到false而不是true扛门。

public static boolean deepEquals(Object a, Object b) {
    if (a == b)
        return true;
    else if (a == null || b == null)
        return false;
    else
        return Arrays.deepEquals0(a, b);
}

Arrays.deepEquals0()方法的源碼為:

static boolean deepEquals0(Object e1, Object e2) {
    assert e1 != null;
    boolean eq;
    if (e1 instanceof Object[] && e2 instanceof Object[])
        eq = deepEquals ((Object[]) e1, (Object[]) e2);
    else if (e1 instanceof byte[] && e2 instanceof byte[])
        eq = equals((byte[]) e1, (byte[]) e2);
    else if (e1 instanceof short[] && e2 instanceof short[])
        eq = equals((short[]) e1, (short[]) e2);
    else if (e1 instanceof int[] && e2 instanceof int[])
        eq = equals((int[]) e1, (int[]) e2);
    else if (e1 instanceof long[] && e2 instanceof long[])
        eq = equals((long[]) e1, (long[]) e2);
    else if (e1 instanceof char[] && e2 instanceof char[])
        eq = equals((char[]) e1, (char[]) e2);
    else if (e1 instanceof float[] && e2 instanceof float[])
        eq = equals((float[]) e1, (float[]) e2);
    else if (e1 instanceof double[] && e2 instanceof double[])
        eq = equals((double[]) e1, (double[]) e2);
    else if (e1 instanceof boolean[] && e2 instanceof boolean[])
        eq = equals((boolean[]) e1, (boolean[]) e2);
    else
        eq = e1.equals(e2);
    return eq;
}

Tips:
1、assert <boolean表達式>:如果<boolean表達式>為true纵寝,則程序繼續(xù)執(zhí)行论寨。如果為false,則程序拋出AssertionError爽茴,并終止執(zhí)行葬凳。
2、assert <boolean表達式> : <錯誤信息表達式>:如果<boolean表達式>為true室奏,則程序繼續(xù)執(zhí)行火焰。如果為false,則程序拋出java.lang.AssertionError胧沫,并輸入<錯誤信息表達式>昌简。

deepEquals()方法的源碼為:

public static boolean deepEquals(Object[] a1, Object[] a2) {
    if (a1 == a2)
        return true;
    if (a1 == null || a2==null)
        return false;
    int length = a1.length;
    if (a2.length != length)
        return false;

    for (int i = 0; i < length; i++) {
        Object e1 = a1[i];
        Object e2 = a2[i];

        if (e1 == e2)
            continue;
        if (e1 == null)
            return false;

        // Figure out whether the two elements are equal
        boolean eq = deepEquals0(e1, e2);

        if (!eq)
            return false;
    }
    return true;
}

四、hashcode()

對象為null時返回0绒怨,否則調(diào)用Object類的hashcode方法纯赎。

public static int hashCode(Object o) {
    return o != null ? o.hashCode() : 0;
}

Object類的hashcode()方法源碼為:

public native int hashCode();

五、hash()

為輸入序列生成hashcode南蹂。此方法返回任意Object序列的hashcode犬金,如果序列過長,int會溢出成負數(shù)六剥,但仍然是唯一的佑附。

public static int hash(Object... values) {
    return Arrays.hashCode(values);
}

其中Arrays.hashcode()方法的源碼為:

public static int hashCode(Object a[]) {
    if (a == null)
        return 0;

    int result = 1;

    for (Object element : a)
        result = 31 * result + (element == null ? 0 : element.hashCode());

    return result;
}

六、toString()

將toString()方法重寫成了如下形式仗考,但最終調(diào)用的還是Object類的toString()方法音同。方法包裝的意義在于支持null值,如果入?yún)閚ull則返回字符串"null"秃嗜。

public static String toString(Object o) {
    return String.valueOf(o);
}

public static String toString(Object o, String nullDefault) {
    return (o != null) ? o.toString() : nullDefault;
}

String.valueOf()方法的源碼為:

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

Object類的toString()方法源碼為:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

七权均、compare()

將普通的compare過程包裝了一下。

public static <T> int compare(T a, T b, Comparator<? super T> c) {
    return (a == b) ? 0 :  c.compare(a, b);
}

八锅锨、requireNonNull()

優(yōu)雅地判空并在對象為空時拋錯叽赊。

public static <T> T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj;
}

public static <T> T requireNonNull(T obj, String message) {
    if (obj == null)
        throw new NullPointerException(message);
    return obj;
}

public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
    if (obj == null)
        throw new NullPointerException(messageSupplier.get());
    return obj;
}

Supplier是一個接口,可以理解為對象提供者必搞。他是一個函數(shù)式編程接口必指,只有一個get()方法。當程序需要一個對象時恕洲,可以通過get()方法來獲取。下面是一個使用示例:

public void test(){    
    // 創(chuàng)建Supplier容器,聲明為TestSupplier類型常拓,此時并不會調(diào)用對象的構(gòu)造方法谐檀,即不會創(chuàng)建對象
    Supplier<RobotUser> user = new RobotUser();
    // 調(diào)用get()方法,此時會調(diào)用對象的構(gòu)造方法,即獲得到真正對象
    RobotUser user1 = user.get();       
}

// 當使用此方法實現(xiàn)get方法時,每次返回的對象都不同
public RobotUser get() {
  return new RobotUser();
}

// 當使用此方法實現(xiàn)get方法時,每次返回的對象都相同
RobotUser user = new RobotUser();
public RobotUser get() {
  return user;
}

九底燎、isNull()

優(yōu)雅地判空并返回結(jié)果。

public static boolean isNull(Object obj) {
    return obj == null;
}

十弹砚、nonNull()

優(yōu)雅地判定非空并返回結(jié)果双仍,與isNull()方法相反。

public static boolean nonNull(Object obj) {
    return obj != null;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末桌吃,一起剝皮案震驚了整個濱河市朱沃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌读存,老刑警劉巖为流,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異让簿,居然都是意外死亡敬察,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門尔当,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莲祸,“玉大人,你說我怎么就攤上這事椭迎∪裰模” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵畜号,是天一觀的道長缴阎。 經(jīng)常有香客問我,道長简软,這世上最難降的妖魔是什么蛮拔? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮痹升,結(jié)果婚禮上建炫,老公的妹妹穿的比我還像新娘。我一直安慰自己疼蛾,他們只是感情好肛跌,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般衍慎。 火紅的嫁衣襯著肌膚如雪转唉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天西饵,我揣著相機與錄音酝掩,去河邊找鬼鳞芙。 笑死眷柔,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的原朝。 我是一名探鬼主播驯嘱,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼喳坠!你這毒婦竟也來了鞠评?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤壕鹉,失蹤者是張志新(化名)和其女友劉穎剃幌,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晾浴,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡负乡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了脊凰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抖棘。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖狸涌,靈堂內(nèi)的尸體忽然破棺而出切省,到底是詐尸還是另有隱情,我是刑警寧澤帕胆,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布朝捆,位于F島的核電站,受9級特大地震影響懒豹,放射性物質(zhì)發(fā)生泄漏芙盘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一歼捐、第九天 我趴在偏房一處隱蔽的房頂上張望何陆。 院中可真熱鬧,春花似錦豹储、人聲如沸贷盲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽巩剖。三九已至铝穷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間佳魔,已是汗流浹背曙聂。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鞠鲜,地道東北人宁脊。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像贤姆,于是被迫代替她去往敵國和親榆苞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 自己備忘,隨便寫 android網(wǎng)絡框架源碼解析及對比 android常用網(wǎng)絡框架對比 Volley: 特點 基于...
    幻海流心閱讀 1,460評論 0 4
  • 面向?qū)ο笾饕槍γ嫦蜻^程霞捡。 面向過程的基本單元是函數(shù)坐漏。 什么是對象:EVERYTHING IS OBJECT(萬物...
    sinpi閱讀 1,054評論 0 4
  • Object類位于java.lang包中,java.lang包有最基礎(chǔ)的和核心的類,在編譯時會自動導入; Obje...
    遇見你的故事閱讀 583評論 0 0
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,811評論 0 11
  • java筆記第一天 == 和 equals ==比較的比較的是兩個變量的值是否相等,對于引用型變量表示的是兩個變量...
    jmychou閱讀 1,497評論 0 3