Java作為一個龐大的知識體系,涉及到的知識點繁多,本文将從Java中最基本的類java.lang.Object開始談起。
Object類位于java.lang包中,java.lang包包含着Java最基礎和核心的類,在編譯時會自動導入。Object類沒有定義屬性,一共有13個方法,具體的類定義結構如下圖:
idea :alt+7
其主要作用是将C/C++中的方法映射到Java中的native方法,實作方法命名的解耦。
private static native void registerNatives();
static {
registerNatives();
}
*傳回這個{@code對象}的運作時類。傳回的
-
{@code類}對象是被{@code鎖定的對象 (效果與Object.class相同。)
被表示類的靜态同步}方法。
public final native Class<?> getClass();
對象重寫euqase方法必須重寫hashcode方法
/**
*
開發者應該注意:先使用hashCode進行篩選,可以提高哈希表的性能
盡可能合理地定義這個方法
* 有些類: 不同的對象(記憶體位址),哈希碼不同;
* 有些類: 不同的内容, 哈希碼不同
* 根據我們的需要決定是否重寫方法,有以上兩種情況,不過不管是哪種情況,根據以上第二、三點,
* 在使用時,(1)我們先用HashCode方法比較兩個對象的哈希值是否相等,若不等,則一定不是同一個
* 對象or内容相同;反之,進第二步判斷
*(2)再用equals方法比較兩個對象是否為同一個對象or内容是否相同,若傳回結果為true,則同一個
*對象or内容相同
*之是以按照這個規則,我想大概基于兩點:i、hashCode其實是将位址or内容采用一種算法進行映射得
*到一種編碼,而equals則是直接比較兩個對象的位址or内容是否相同。 是以,hashCode存在沖突的
*現象————内容or位址不同的2個對象,hashCode值相同 ii、盡管equals是直接比較,但是其消耗較大
*是以,先用hashCode有助于提高性能,篩選掉大部分情況(畢竟沖突時小機率事件)
@return
*/
public native int hashCode();/**
注意是非空對象的等價關系,也就是說,null不能調用
- 性質1、反射性--任何 非空引用 調用自身,傳回結果都是true
- 2、 對稱性--兩個引用 互相調用,傳回結果一樣
-
3、 傳遞性
4、 一緻性--兩個對象之間的調用 多少次還是那個結果 前提是沒有資訊被修改
- 5、 任意非空引用 調用null 傳回的都是false
- 不管equals方法有沒有重寫,我們都要重寫hashCode方法
*進而保證————equal的對象(無重寫:記憶體位址相同,指向同一個對象;有重寫:内容相同)
*具有相同的hashCode值:for 位址or 内容的各個位 + hashCode算法 ==得到 相同的值
*/
public boolean equals(Object obj) {
return (this == obj); // 比較的是兩個對象的記憶體位址
// 前面總是說reference object,也就是引用型資料,而不是基本類型資料(比較簡單)
//基本資料類型一般都是用 ==
}
/**
- (1)clone方法是産生對象的一個獨立副本
- (2)對象x和它clone的獨立副本 調用getClass方法 結果一樣
- * 但這些不是絕對的條件(意思是clone可以重寫嗎?)
- * x的clone副本 和 自己 equal 但是不是絕對的(意思是如果equal的是位址的話就不一定?)
- 按照慣例,傳回的對象應該通過super.clone調用得到
- *如果一個類和它所有父類遵循這個慣例,那麼x.clone().getClass() == x.getClass()
- 按照慣例,傳回的對象是獨立的
- *為了實作這個獨立性,傳回副本之前 有必要修改這個對象的一個or多個元素
- *通常,這意味着複制組成這個對象深層結構的所有可變元素,并用副本的引用替換這些元素的引用
- *如果一個類隻包含原始字段、不可變元素的引用,那麼super.clone傳回的對象 沒有字段需要修改
- *大概意思: 淺拷貝 隻複制引用的值,沒有複制可變元素所引用的對象
*/
protected native Object clone() throws CloneNotSupportedException;
深克隆與淺克隆
/**
*傳回這個對象的 字元串表示
*建議所有子類重寫此方法
傳回的字元串包括:類的名字、@、對象的16進制表示的哈希值
• @return
*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}/**
- 喚醒在這個對象的螢幕上的 一個等待線程
*如果有線程在等待隊列中等待(通過調用wait方法,一個線程在對象的螢幕上等待),其中的一個
*被選中喚醒。這種選擇是任意的,根據算法進行競争(最着急的線程)
喚醒的線程将無法繼續(被其他對象使用?在等待) 直到目前線程放棄對這個對象的鎖定
*被喚醒的線程 以通用的方式 與任何其他(積極競争同步這個對象的)線程競争
*同步,是說沒有特權,都有機會成為能夠鎖定該對象的線程
這個方法隻能被一個線程(這個線程是 對象的螢幕的所有者)調用
*一個線程可以以3種方式 成為這個對象的螢幕的所有者
1、在調用notify()之前,線程必須獲得該對象的對象級别鎖
* 2、執行完notify()方法後,不會馬上釋放鎖,要直到退出synchronized代碼塊,目前線程才會釋放
*鎖
* 3、notify()一次隻随機通知一個線程進行喚醒
原則:一次隻能有一個線程 擁有一個對象的螢幕
如果目前線程 不是這個對象的monitor的所有者,抛出IllegalMonitorStateException
*/
public final native void notify();
//喚醒所有 等待在這個對象的螢幕上的線程
public final native void notifyAll();
//實作二:使線程進入等待狀态,直到被notify or notifyAll調用
public final native void wait(long timeout) throws InterruptedException;
//第一種實作:使線程進入等待狀态,直到被notify or notifyAll調用 or 等待時間達到限定值
//timeout - 要等待的最長時間(以毫秒為機關)。
//nanos - 額外時間(以毫微秒為機關,範圍是 0-999999)
//逾時時間=1000000*timeout+nanos(毫微秒)。
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);
}
//實作二:使線程進入等待狀态,直到被notify or notifyAll調用
public final void wait() throws InterruptedException {
wait(0);
}
//當垃圾回收器将要回收對象所占記憶體之前被調用
protected void finalize() throws Throwable { }
作者:三号小玩家