日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java Object类的各个方法

發(fā)布時間:2023/12/10 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java Object类的各个方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Java中所有的類都繼承自java.lang.Object類,Object類中一共有11個方法:

public final native Class<?> getClass();public native int hashCode();public boolean equals(Object obj) {return (this == obj); }protected native Object clone() throws CloneNotSupportedException;public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode()); }public final native void notify();public final native void notifyAll();public final native void wait(long timeout) throws InterruptedException;public final void wait(long timeout, int nanos) throws InterruptedException {if (timeout < 0) {throw new IllegalArgumentException("timeout value is negative");}if (nanos < 0 || nanos > 999999) {throw new IllegalArgumentException("nanosecond timeout value out of range");}if (nanos > 0) {timeout++;}wait(timeout); }public final void wait() throws InterruptedException {wait(0); }protected void finalize() throws Throwable { }

getClass方法

這是一個native方法,并且是'final'的,也就是說這個方法不允許在子類中覆寫。
getClass方法返回的是當(dāng)前實例對應(yīng)的Class類,也就是說不管一個類有多少個實例,每個實例的getClass返回的Class對象是一樣的。請看下面的例子:

Integer i1 = new Integer(1); Class i1Class = i1.getClass();Integer i2 = new Integer(1); Class i2Class = i2.getClass(); System.out.println(i1Class == i2Class);

上面的代碼運行結(jié)果為true,也就是說兩個Integer的實例的getClass方法返回的Class對象是同一個。

Integer.class和int.class

Java中還有一個方法可以獲取Class,例如我們想獲取一個Integer實例對應(yīng)的Class,可以直接通過Integer.class來獲取,請看下面的例子:

Integer num = new Integer(1); Class numClass = num.getClass(); Class integerClass = Integer.class; System.out.println(numClass == integerClass);

上面代碼的運行結(jié)果為true,也就是說通過調(diào)用實例的getClass方法和類.class返回的Class是一樣的。與Integer對象的還有int類型的原生類,與Integer.class對應(yīng),int.class用于獲取一個原生類型int的Class。但是他們兩個返回的不是同一個對象。請看下面的例子:

Class intClass = int.class; Class intTYPE = Integer.TYPE; Class integerClass = Integer.class; System.out.println(intClass == integerClass); System.out.println(intClass == intTYPE);

上面的代碼運行結(jié)果是:

false true

Integer.class和int.class返回的不是一個對象,而int.class返回的和Integer.TYPE是同一個對象。Integer.TYPE定義如下:

public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");

Java中為原生類型(boolean,byte,char,short,int,long,float,double)和void都創(chuàng)建了一個預(yù)先定義好的類型,可以通過包裝類的TYPE靜態(tài)屬性獲取。上述的Integer類中TYPE和int.class是等價的。

hashCode方法

對象的哈希碼主要用于在哈希表中的存放和查找等。Java中對于對象hashCode方法的規(guī)約如下:

  • 在java程序執(zhí)行過程中,在一個對象沒有被改變的前提下,無論這個對象被調(diào)用多少次,hashCode方法都會返回相同的整數(shù)值。對象的哈希碼沒有必要在不同的程序中保持相同的值。
  • 如果2個對象使用equals方法進行比較并且相同的話,那么這2個對象的hashCode方法的值也必須相等。
  • 如果根據(jù)equals方法,得到兩個對象不相等,那么這2個對象的hashCode值不需要必須不相同。但是,不相等的對象的hashCode值不同的話可以提高哈希表的性能。
  • 為了理解這三條規(guī)約,我們來先看一下HashMap中put一個entry的過程:

    public V put(K key, V value) {return putVal(hash(key), key, value, false, true); }final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;if ((p = tab[i = (n - 1) & hash]) == null) // 這里key的hashcode被用來定位當(dāng)前entry在哈希表中的indextab[i] = newNode(hash, key, value, null); // 如果當(dāng)前哈希表中沒有key對應(yīng)的entry,則直接插入else {// 當(dāng)前哈希表中已經(jīng)有了key對應(yīng)的entry了,則找到這個節(jié)點,然后看是否需要更新這個entry的valueNode<K,V> e; K k;// 判斷當(dāng)前節(jié)點就是已經(jīng)存在的entry的條件:1:hashcode相等;2:當(dāng)前節(jié)點的key和key是同一個對象(==)或者兩者的equals方法判定相等if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {for (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}// 是否需要更新舊值,如果需要更新則更新if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null; }

    HashMap中put一個鍵值對時有以下幾個步驟:

  • 計算key的哈希碼,通過哈希碼定位新增的entry應(yīng)該處于哈希表中的哪個位置,如果當(dāng)前位置為null,則代表哈希表中沒有key對應(yīng)的entry,直接新插入一個節(jié)點就好了。
  • 如果當(dāng)前key在哈希表中已經(jīng)有了映射,則先查找這個節(jié)點,判定當(dāng)前是否為目標節(jié)點的條件有兩個:1)兩者的哈希碼必須相等;2)兩者是同一個對象(==成立),或者兩者的equals方法判定兩者相等。
  • 判斷是否需要更新舊值,需要的話就更新。
  • 分析完了HashMap的put操作后,我們再來看看這三條規(guī)約:

  • 第一條規(guī)約要求多次調(diào)用一個對象的hashCode方法返回的值要相等。設(shè)想如果一個key的hashCode方法每次返回值如果不同,則在put的時候就可能定位到哈希表中不同的位置,就產(chǎn)生了歧義:明明兩個key是同一個,但是哈希表中存在同一個key的多個不同映射。這就違背了哈希表的key不能重復(fù)的原則了。
  • 第二條規(guī)約也很好理解:如果兩個key的equals方法判定兩者相等,則說明哈希表中只需要保留一個key就行了。如果equals判定相等,而hashcode不同,則就會違背這個事實。
  • 第三條規(guī)約是用來優(yōu)化哈希表的性能的,如果哈希表put時"碰撞"太多,勢必會造成查找性能下降。
  • equals方法

    equals方法用于判定兩個對象是否相等。Object中的equals方法其實默認比較的是兩個對象是否擁有相同的地址。也就是"=="對應(yīng)的內(nèi)存語義。

    但是在子類中我們可以覆寫equals來判定子類的兩個實例是否為同一個對象。例如對于一個人來說,他有很多屬性,但是每個人的id是唯一的,如果兩個人的id一樣則證明兩個人是同一個人,而不管其他屬性是否一樣。這個時候我們就可以覆寫人的equals方法來保證這點了。

    public class Person {private long id;private String name;private int age;private String nation;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return id == person.id; // 如果兩個person的id相同,則我們認為他們是同一個對象}@Overridepublic int hashCode() {return Objects.hash(id);} }

    equals方法在非空對象引用上的特性:

  • reflexive,自反性。任何非空引用值x,對于x.equals(x)必須返回true
  • symmetric,對稱性。任何非空引用值x和y,如果x.equals(y)為true,那么y.equals(x)也必須為true
  • transitive,傳遞性。任何非空引用值x、y和z,如果x.equals(y)為true并且y.equals(z)為true,那么x.equals(z)也必定為true
  • consistent,一致性。任何非空引用值x和y,多次調(diào)用 x.equals(y) 始終返回 true 或始終返回 false,前提是對象上 equals 比較中所用的信息沒有被修改
  • 對于任何非空引用值 x,x.equals(null) 都應(yīng)返回 false
  • Java要求一個類的equals方法和hashCode方法同時覆寫。我們剛剛分析了HashMap中對于key的處理過程:首先根據(jù)key的哈希碼定位哈希表中的位置,其次根據(jù)"=="或者equals方法判定兩個key是否相同。如果Person的equals方法沒有被覆寫,則兩個Person對象即使id一樣,但是不是指向同一塊內(nèi)存地址,那么哈希表中就查找不到已經(jīng)存在的映射entry了。

    clone方法

    用于克隆一個對象,被克隆的對象需要implements Cloneable接口,否則調(diào)用這個對象的clone方法,將會拋出CloneNotSupportedException異常。克隆的對象通常情況下滿足以下三條規(guī)則:

  • x.clone() != x,克隆出來的對象和原來的對象不是同一個,指向不同的內(nèi)存地址
  • x.clone().getClass() == x.getClass()
  • x.clone().equals(x)
  • 一個對象進行clone時,原生類型和包裝類型的field的克隆原理不同。對于原生類型是直接復(fù)制一個,而對于包裝類型,則只是復(fù)制一個引用而已,并不會對引用類型本身進行克隆。

    淺拷貝

    淺拷貝例子:

    public class ShallowCopy {public static void main(String[] args){Man man = new Man();Man manShallowCopy = (Man) man.clone();System.out.println(man == manShallowCopy);System.out.println(man.name == manShallowCopy.name);System.out.println(man.mate == manShallowCopy.mate);} }class People implements Cloneable {// primitive typepublic int id;// reference typepublic String name;@Overridepublic Object clone() {try {return super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;} }class Man extends People implements Cloneable {// reference typepublic People mate = new People();@Overridepublic Object clone() {return super.clone();} }

    上面的代碼的運行結(jié)果是:

    false true true

    通過淺拷貝出來的Man對象manShallowCopy的name和mate屬性和原來的對象man都指向了相同的內(nèi)存地址。在對Man的name和mate進行拷貝時淺拷貝只是對引用進行了拷貝,指向的還是同一塊內(nèi)存地址。

    深拷貝

    對一個對象深拷貝時,對于對象的包裝類型的屬性,會對其再進行拷貝,從而達到深拷貝的目的,請看下面的例子:

    public class DeepCopy {public static void main(String[] args){Man man = new Man();Man manDeepCopy = (Man) man.clone();System.out.println(man == manDeepCopy);System.out.println(man.mate == manDeepCopy.mate);} }class People implements Cloneable {// primitive typepublic int id;// reference typepublic String name;@Overridepublic Object clone() {try {return super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;} }class Man extends People implements Cloneable {// reference typepublic People mate = new People();// 深拷貝Man@Overridepublic Object clone() {Man man = (Man) super.clone();man.mate = (People) this.mate.clone(); // 再對mate屬性進行clone,從而達到深拷貝return man;} }

    上面代碼的運行結(jié)果為:

    false false

    Man對象的clone方法中,我們先對Man進行了clone,然后對mate屬性也進行了拷貝。因此man的mate和manDeepCopy的mate指向了不同的內(nèi)存地址。也就是深拷貝。

    通常來說對一個對象進行完完全全的深拷貝是不現(xiàn)實的,例如上面的例子中,雖然我們對Man的mate屬性進行了拷貝,但是無法對name(String類型)進行拷貝,拷貝的還是引用而已。

    toString方法

    Object中默認的toString方法如下:

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

    也就是class的名稱+對象的哈希碼。一般在子類中我們可以對這個方法進行覆寫。

    notify方法

    notify方法是一個final類型的native方法,子類不允許覆蓋這個方法。

    notify方法用于喚醒正在等待當(dāng)前對象監(jiān)視器的線程,喚醒的線程是隨機的。一般notify方法和wait方法配合使用來達到多線程同步的目的。
    在一個線程被喚醒之后,線程必須先重新獲取對象的監(jiān)視器鎖(線程調(diào)用對象的wait方法之后會讓出對象的監(jiān)視器鎖),才可以繼續(xù)執(zhí)行。

    一個線程在調(diào)用一個對象的notify方法之前必須獲取到該對象的監(jiān)視器(synchronized),否則將拋出IllegalMonitorStateException異常。同樣一個線程在調(diào)用一個對象的wait方法之前也必須獲取到該對象的監(jiān)視器。

    wait和notify使用的例子:

    Object lock = new Object(); Thread t1 = new Thread(() -> {synchronized (lock) {System.out.println(Thread.currentThread().getName() + " is going to wait on lock's monitor");try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " relinquishes the lock's monitor");} }); Thread t2 = new Thread(() -> {synchronized (lock) {System.out.println(Thread.currentThread().getName() + " is going to notify a thread that waits on lock's monitor");lock.notify();} }); t1.start(); t2.start();

    notifyAll方法

    notifyAll方法用于喚醒所有等待對象監(jiān)視器鎖的線程,notify只喚醒所有等待線程中的一個。

    同樣,如果當(dāng)前線程不是對象監(jiān)視器的所有者,那么調(diào)用notifyAll同樣會發(fā)生IllegalMonitorStateException異常。

    wait方法

    public final native void wait(long timeout) throws InterruptedException;

    wait方法一般和上面說的notify方法搭配使用。一個線程調(diào)用一個對象的wait方法后,線程將進入WAITING狀態(tài)或者TIMED_WAITING狀態(tài)。直到其他線程喚醒這個線程。

    線程在調(diào)用對象的wait方法之前必須獲取到這個對象的monitor鎖,否則將拋出IllegalMonitorStateException異常。線程的等待是支持中斷的,如果線程在等待過程中,被其他線程中斷,則拋出InterruptedException異常。

    如果wait方法的參數(shù)timeout為0,代表等待過程是不會超時的,直到其他線程notify或者被中斷。如果timeout大于0,則代表等待支持超時,超時之后線程自動被喚醒。

    finalize方法

    protected void finalize() throws Throwable { }

    垃圾回收器在回收一個無用的對象的時候,會調(diào)用對象的finalize方法,我們可以覆寫對象的finalize方法來做一些清除工作。下面是一個finalize的例子:

    public class FinalizeExample {public static void main(String[] args) {WeakReference<FinalizeExample> weakReference = new WeakReference<>(new FinalizeExample());weakReference.get();System.gc();System.out.println(weakReference.get() == null);}@Overridepublic void finalize() {System.out.println("I'm finalized!");} }

    輸出結(jié)果:

    I'm finalized! true

    finalize方法中對象其實還可以"自救",避免垃圾回收器將其回收。在finalize方法中通過建立this的一個強引用來避免GC:

    public class FinalizeExample {private static FinalizeExample saveHook;public static void main(String[] args) {FinalizeExample.saveHook = new FinalizeExample();saveHook = null;System.gc();System.out.println(saveHook == null);}@Overridepublic void finalize() {System.out.println("I'm finalized!");saveHook = this;} }

    輸出結(jié)果:

    I'm finalized! false



    作者:zhong0316
    鏈接:https://www.jianshu.com/p/852faf4dc8f1
    來源:簡書
    簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。

    總結(jié)

    以上是生活随笔為你收集整理的Java Object类的各个方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美成人精品欧美一级乱黄 | 久久免费少妇高潮久久精品99 | 国产精品一区二区无码对白 | 懂色aⅴ一区二区三区免费 国产精品99在线观看 | 国产1页| 国产精品毛片久久久久久久av | 欧美aⅴ| 在线观看亚洲大片短视频 | 无码人妻精品一区二区中文 | 91婷婷射| 天天摸天天碰 | 国产高清一区二区三区 | 快播av在线 | 亚欧成人精品一区二区 | 97伊人超碰| 午夜激情成人 | 91成人免费网站 | 亚洲精品视频一区二区三区 | 欧美xxxxxxxxx| 久久久久久欧美 | 久久久久人妻精品色欧美 | 久久精品国产亚洲AV无码麻豆 | 俺也去在线视频 | 精品久久精品久久 | 免费古装一级淫片潘金莲 | 99自拍| 国产高潮视频在线观看 | 日韩网红少妇无码视频香港 | 欧美 日韩 国产 激情 | 无码人妻少妇伦在线电影 | 天天操天天操天天操天天操 | 蜜臀在线播放 | 亚洲av无码一区二区三区观看 | 想要xx在线观看 | 国产精品福利导航 | 国产欧美一区二区在线 | 日韩精品第一页 | 无套在线观看 | 亚洲一区二区三区免费在线观看 | 毛片久久久久久久 | av日韩精品 | 亚洲精品乱码久久久久久日本蜜臀 | 欧美亚洲天堂 | 日韩三级av | 99视频在线精品免费观看2 | 毛片无码一区二区三区a片视频 | 芒果视频污污 | 少妇一级淫片免费播放 | 尹人久久| 日韩在线影院 | 久久综合视频网 | 国偷自产av一区二区三区 | 天堂在线中文网 | 蜜桃精品噜噜噜成人av | av新天堂 | 日韩欧美中文字幕一区 | 国产亚洲成av人片在线观看桃 | 亚洲情射| 四虎影库在线播放 | 人人艹人人爽 | 欧美gv在线 | 都市激情男人天堂 | 日本视频在线 | 偷自在线 | 四虎免看黄 | 欧美极品jizzhd欧美 | 男人日女人的网站 | 成人av电影在线播放 | 性欧美videos另类艳妇3d | 91天天爽 | 亚洲精品大片www | 青春草网站 | 婷婷五月情 | 在线不卡的av | 日韩精品欧美激情 | 亚洲成人播放器 | 日本免费一区二区三区最新 | 成人免费短视频 | 欧美 日韩 高清 | av优选在线观看 | 国产精品成熟老女人 | 欧美黄视频 | 成年网站免费观看 | 久久久久久国产精品三级玉女聊斋 | 色窝窝无码一区二区三区 | 女人喂男人奶水做爰视频 | 蜜桃av免费在线观看 | 亚洲va视频 | 成人精品在线看 | 狠狠爱av| 亚洲成人自拍网 | 黄色一及毛片 | 黄色草逼网站 | 亚洲国产综合视频 | 欧美老女人性视频 | 午夜免费播放观看在线视频 | 97在线超碰| 亚洲色图视频网站 | 色丁香久久 |