快訊 >

        環球時訊:Java基礎類源碼分析:Object

        時間:2023-02-22 04:22:11       來源:騰訊云

        1 大綱

        java.lang.Object是所有類的父類,默認繼承,而且java.lang包下的所有類都由編譯器自動導入,不需要顯示import,因為用的多,提前加載可以提高運行時速度。

        image.png

        2 equals方法

        "=="與equals的區別要看equals是如何重寫的,在Object中兩者意義等同,都是判斷引用地址是否相同。在String中equals比較的是內容。

        //Objectpublic boolean equals(Object obj) {    return (this == obj);}//Stringpublic boolean equals(Object anObject) {    if (this == anObject) {        return true;    }    return (anObject instanceof String aString)            && (!COMPACT_STRINGS || this.coder == aString.coder)            && StringLatin1.equals(value, aString.value);}public static boolean equals(byte[] value, byte[] other) {    if (value.length == other.length) {        for (int i = 0; i < value.length; i++) {            if (value[i] != other[i]) {                return false;            }        }        return true;    }    return false;}

        equals方法含義按需要重寫,但需要滿足Java規范:


        (資料圖片)

        在Java規范中,對equals方法的使用必須遵循以下幾個原則:1)自反性。對于任何非空引用值x,x. equals(x)都應返回true。2)對稱性。對于任何非空引用值x和y,當且僅當y. equals(x)返回true時,x.equals(y)才應返回true。3)傳遞性。對于任何非空引用值x、y和z,如果x. equals(y)返回true,并且y.equals(z)返回true,那么x. equals(z)應返回true。4)一致性。對于任何非空引用值x和y,多次調用x. equals(y)始終返回true或始終返回false,前提是對象上equals比較中所用的信息沒有被修改。對于任何非空引用值x,x. equals(null)都應返回false。對于任何非空引用值x,x. equals(null)都應返回false。

        3 hashCode方法

        hashCode是一個本地方法,用來加快equals比較,但兩個不同對象的哈希值難免有沖突,hashCode和equals的關系如下:

        如果equals返回true,則hashCode一定相等;如果equals返回false,則hashCode可能相等。也就是說如果hashCode不相等,那么equals一定不相等。注:Object中的hashCode方法返回的是對象的內存地址,有特殊要求可重寫。

        @IntrinsicCandidatepublic native int hashCode();

        hashCode主要用于Map、Set等容器中,當向容器添加元素時需要去一個個比較是否有相等的元素,直接調用equals效率太慢。可以先比較hashCode,如果hashCode不一樣則equals必然返回false,如果hashCode一樣再調用equals比較。

        image.png

        4 wait

        wait方法也是Object類本地方法,一般用于synchronize代碼塊中,作用是釋放鎖并阻塞線程,喚醒方法是notify/notifyAll。

        sleep方法是Thread類方法,調用了sleep0本地方法,作用是不釋放鎖但阻塞線程。

        await方法是ConditionObject/ReentrantLock類的方法,作用是釋放鎖并阻塞線程,喚醒方法是signal/signalAll。

        public final void wait() throws InterruptedException {    wait(0L);}public final void wait(long timeoutMillis) throws InterruptedException {    long comp = Blocker.begin();    try {        wait0(timeoutMillis);    } catch (InterruptedException e) {        Thread thread = Thread.currentThread();        if (thread.isVirtual())            thread.getAndClearInterrupt();        throw e;    } finally {        Blocker.end(comp);    }}// final modifier so method not in vtableprivate final native void wait0(long timeoutMillis) throws InterruptedException;public final void wait(long timeoutMillis, int nanos) throws InterruptedException {    if (timeoutMillis < 0) {        throw new IllegalArgumentException("timeoutMillis value is negative");    }    if (nanos < 0 || nanos > 999999) {        throw new IllegalArgumentException(                            "nanosecond timeout value out of range");    }    if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {        timeoutMillis++;    }    wait(timeoutMillis);}
        public static void sleep(long millis) throws InterruptedException {    if (millis < 0) {        throw new IllegalArgumentException("timeout value is negative");    }    if (currentThread() instanceof VirtualThread vthread) {        long nanos = MILLISECONDS.toNanos(millis);        vthread.sleepNanos(nanos);        return;    }    if (ThreadSleepEvent.isTurnedOn()) {        ThreadSleepEvent event = new ThreadSleepEvent();        try {            event.time = MILLISECONDS.toNanos(millis);            event.begin();            sleep0(millis);        } finally {            event.commit();        }    } else {        sleep0(millis);    }}private static native void sleep0(long millis) throws InterruptedException;

        await具體細節請看Java多線程:條件變量

        public final void await() throws InterruptedException {    if (Thread.interrupted())        throw new InterruptedException();    ConditionNode node = new ConditionNode();    int savedState = enableWait(node);//加入條件隊列    LockSupport.setCurrentBlocker(this); // for back-compatibility,將AQS對象設置到thread中    boolean interrupted = false, cancelled = false, rejected = false;    while (!canReacquire(node)) {//如果被喚醒進入同步隊列后就可以跳出循環        if (interrupted |= Thread.interrupted()) {            if (cancelled = (node.getAndUnsetStatus(COND) & COND) != 0)                break;              // else interrupted after signal        } else if ((node.status & COND) != 0) {            try {                if (rejected)                    node.block();                else                    ForkJoinPool.managedBlock(node);//阻塞線程,最終會調用LockSupport.park()            } catch (RejectedExecutionException ex) {                rejected = true;            } catch (InterruptedException ie) {                interrupted = true;            }        } else            Thread.onSpinWait();    // awoke while enqueuing    }//被喚醒    LockSupport.setCurrentBlocker(null);    node.clearStatus();////lock.lock()方法:acquire(null, arg, false, false, false, 0L);//重新獲取鎖時已原來的savedState    acquire(node, savedState, false, false, false, 0L);//重新獲取鎖,此時該節點已經進入了同步隊列,有可能直接tryAcquire成功跳出循環,也可能需要兩次循環修改node.status為WAITING、park。    if (interrupted) {        if (cancelled) {            unlinkCancelledWaiters(node);            throw new InterruptedException();        }        Thread.currentThread().interrupt();    }}

        5 附錄

        public class Object {    @IntrinsicCandidate    public Object() {}    @IntrinsicCandidate    public final native Class getClass();//返回類對象用于反射    @IntrinsicCandidate    public native int hashCode();    public boolean equals(Object obj) {        return (this == obj);    }    @IntrinsicCandidate    protected native Object clone() throws CloneNotSupportedException;    public String toString() {        return getClass().getName() + "@" + Integer.toHexString(hashCode());    }    @IntrinsicCandidate    public final native void notify();    @IntrinsicCandidate    public final native void notifyAll();    public final void wait() throws InterruptedException {        wait(0L);    }    public final void wait(long timeoutMillis) throws InterruptedException {        long comp = Blocker.begin();        try {            wait0(timeoutMillis);        } catch (InterruptedException e) {            Thread thread = Thread.currentThread();            if (thread.isVirtual())                thread.getAndClearInterrupt();            throw e;        } finally {            Blocker.end(comp);        }    }    // final modifier so method not in vtable    private final native void wait0(long timeoutMillis) throws InterruptedException;    public final void wait(long timeoutMillis, int nanos) throws InterruptedException {        if (timeoutMillis < 0) {            throw new IllegalArgumentException("timeoutMillis value is negative");        }        if (nanos < 0 || nanos > 999999) {            throw new IllegalArgumentException(                                "nanosecond timeout value out of range");        }        if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {            timeoutMillis++;        }        wait(timeoutMillis);    }    @Deprecated(since="9", forRemoval=true)    protected void finalize() throws Throwable { }}

        關鍵詞: Java JavaScript Node.js

        首頁
        頻道
        底部
        頂部
        閱讀下一篇

        亚洲国产成人精品无码区在线观看 | 久久久久久亚洲精品不卡| 亚洲制服丝袜中文字幕| 老司机亚洲精品影院| 国产亚洲精品a在线观看app| 亚洲一区日韩高清中文字幕亚洲 | 亚洲av无码专区在线电影| 亚洲一卡一卡二新区无人区 | 亚洲无人区午夜福利码高清完整版| 亚洲免费无码在线| 久久久久国产成人精品亚洲午夜| 亚洲人成网站色在线入口| 亚洲午夜福利精品无码| 综合亚洲伊人午夜网| 在线亚洲人成电影网站色www| 亚洲精品无码不卡在线播放HE| 亚洲人成人无码网www电影首页| 最新亚洲成av人免费看| 亚洲国产日韩在线视频| 亚洲av无码精品网站| 亚洲国产精品一区二区久久| 亚洲资源在线观看| 亚洲精品亚洲人成在线麻豆| 亚洲乱码一二三四区麻豆| 亚洲天堂2016| 亚洲AV无码专区亚洲AV桃| 国产综合成人亚洲区| 国产日产亚洲系列最新| 国产精品亚洲精品日韩已满| 亚洲爱情岛论坛永久| 亚洲欧洲日产国码二区首页| tom影院亚洲国产一区二区| 亚洲色偷偷综合亚洲av78| 国产精品亚洲av色欲三区| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 伊人久久大香线蕉亚洲五月天| 国产aⅴ无码专区亚洲av| 亚洲日本精品一区二区| 亚洲国产精品久久人人爱| 亚洲人成色777777精品| 亚洲成A人片在线观看无码3D|