
當我們寫一個類的時候都會對Java.lang.類的一些重要方法進行重寫這些方法包含(),(),(),(),clone(),wait(),()/() 這八個方法。一 ()方法1.何時需要對代碼方法進行重寫?當一個類里面, 它自己有自己特有的那種邏輯相等的概念, 然后這個邏輯相等的概念呢, 是不同于對象身份的概念的。2.設計()使用操作符來檢查實參是否為正確的類型。對于該類當中的每一個關鍵域, 需要針對實里面所提供的對應的那個域的數(shù)值情況, 去仔細地與目前所持有的這個對象內部所對應的這些域的數(shù)值之間展開檢查處理。對于那些, 不屬于float類型以及類型的原語類型字段來說, 應該采用相等符號進行數(shù)值上的比對操作, 以確保它們的值是完全一致的。針對對象引用領域, 將遞歸調用方法進行處理。針對float這個類型的字段, 采取辦法是先調用Float點括號來把它轉換成整數(shù)類型, 之后再使用雙等號來進行比較操作。對于域這個概念, 我們是先借助點括號的方法把它轉換成為長整型數(shù)據, 接著再去執(zhí)行相等性檢查操作來比較它們的值。針對數(shù)組類型這一種數(shù)據領域的具體情況, 需要去調用對應的那個方法。二 ()方法1.當進行改寫某個內容的操作的時候, 往往總是要針對另一個方面或者內容來進行相應的改寫處理工作。參考改寫后的類定義中的方法, 邏輯上可能認為兩個完全不同的實例是相等的, 可要是用某個特定的.方法來判斷的話, 它們就僅僅是兩個分開的對象而已, 這樣一來, 就違背了這樣的規(guī)定, 就是相等的東西, 它們的散列碼也得一樣才行。2.設計()將某個不是零的一個常數(shù)數(shù)值, 比如說17這一個數(shù)字, 給保存到一個int類型的一個變量里面去。對于該對象里面的每一個關鍵的域 f 來說, 這里所說的關鍵的域 f, 意思就是在具體的方法里面會被考慮到的那一個具體的字段。這個類型的計算方法是將表達式 f?? 0 : 1 進行計算。對于byte型數(shù)據, 對于char型數(shù)據, 對于short型數(shù)據, 都需要執(zhí)行轉換為int型的計算。這是一個long類型的數(shù)據, 計算的過程是先對它進行強制轉換變?yōu)閕nt類型, 然后把這個數(shù)據和它的右移32位之后的結果按位異或。這是一個float浮點數(shù)類型, 在計算的時候需要使用Float方法。這種類型, 進行計算操作, 最終獲取到一個長整型的數(shù)值結果, 隨后再次執(zhí)行該步驟。對象引用, 遞歸調用該對象的所屬類的成員方法。數(shù)組域對其中每個元素調用它的方法。把通過上面步驟計算得到的那個散列碼, 存到名為c的那個整型變量里面去, 然后接下來去執(zhí)行等于三十七乘以之前某個值再加上這個c的那一步計算操作。執(zhí)行返回這一動作。三 ()方法關于我們所使用的各種方法, 這些方法在我們日常生活的各個領域里面都被普遍應用著, 可以說是占據了一個極其重要位置的小型知識點類別, 這里我就給大家做一個大體上面的講解和說明。我們翻閱了API這一文檔, 查看那個名稱為java.lang.類的這些方法, 它們詳細的描述是這樣子寫著的:()這是關于這一事項的一個方面。在里面提到的時候, 有這樣一種情況, 那就是“這個”被提及的這個內容。這一個東西本應該是屬于某一個特定對象的, 但是大家普遍認為這對于任意一個對象來說都是很容易去閱讀的這樣一個狀態(tài)。因此可以說是有必要讓所有的相關方都參與到這一件事兒的處理過程中來。The for class a of the name of the class of which the is an , the at-sign , and the of the hash code of the . In other words, this a equal to the value of:首先(), 然后()接著是()最后是。(())。:這是一個a的部分的。我們對上述內容進行大致性的解析與翻譯處理。該函數(shù)會返回一個字符串, 這個字符串是能夠代表當前對象的。通常來說, 這個方法返回的是對象的“文本表達式”。這種最終獲得的結果形式是非常簡潔的。但是, 這樣并不是那種方便人們去閱讀的信息展示方式。因此, 這里鄭重建議大家, 在您自己去編寫子類的時候, 最好對這一方法進行重新定義與實現(xiàn)。對于這個類來講, 方法返回值是由所屬類的類的名稱、一個符號名為的字符、還有這個對象的哈希值的沒有符號的十六進制的表達形式所共同組成的。換句話說, 這個方法返回來的這些字符串和下面的這個方法所返回的那些數(shù)值是完全等同的。這個表達式看起來是缺失了具體的函數(shù)名或者變量名稱。返回把那個對象的字符串樣子給表現(xiàn)出來。隨后, 我們不妨將目光轉向 java.lang. 類中所包含的方法部分, 深入考察一下那些內容在程度上是否具有相同之處呢。()This (which is a !) is .by:in:in class:the .我們依舊還是打算進行一下翻譯這件事的吧。這個對象自己呀, 它已經就是一個字符串了, 那它也就是那個返回值。說明接口中的方法重寫重寫了中的方法返回那個句子就是它自己本身所包含的那個字符串。我們可以看到, 這是一個類的實例繼承自另一個類, 并且對這個方法進行了重寫操作, 也就是說它擁有了屬于自己的一套具體的邏輯處理方式, 該方法的作用是把調用者自身轉換為一個字符串形式的內容并返回回去, 由于這個對象在被當作字符串使用時本身就已經具備字符串類型的特征或者說是本質上就是字符串類型的一個具體表現(xiàn), 所以在后續(xù)的操作當中或者說在內存的管理環(huán)節(jié)里頭, 就完全沒必要去再去生成或者引用一大堆毫無意義的哈希碼值了。為了把這個事情說得更清楚一些, 我們在說明的這段內容中可以看出來, 中方法它就是接口的一個方法, 所以呢, 我們現(xiàn)在就去查看一下 java.lang 這個接口里面的方法的定義情況是怎樣的。()a the in this in the same order as this . The of the will be the of this .:in class:這是一個of this of。咱們還是把它翻譯一下。返回值是一個字符串對象, 該對象里面裝著跟這個序列的順序一樣的所有字符, 這個字符串的長度, 就是那個序列的長度。重寫的返回這個字符串是由該序列里面的特定的字符所組成的。第四點, 是關于那個名為clone這個方法的內容。針對克隆, 也就是那個英文單詞叫Clone的事情, Java它有一些那個限制。1、被克隆的類必須由它來自己去實現(xiàn)那個接口, 這樣做是為了表示 .clone() 這個方法能夠對這一個類的實例進行字段的復制, 而且這個操作是合法的。這個接口實際上是一個標識用的接口, 它里面沒有任何接口方法。2、那些需要去實現(xiàn)對應的接口的這些類, 它們都應該把自己的.clone這個方法給重新實現(xiàn)一遍, 也就是要進行重寫操作, 至于說它原本的那個狀態(tài), 是處于受保護的一個權限級別的。3、在Java.lang.包之中, 那個被叫做克隆的方法, 它的具體定義是這樣的:clone()請創(chuàng)建并返回那個對象的一個副本, 這是一個受保護的方法, 只有在同一個包里面才可以看到它。按照大家一直以來的習慣, 返回出來的那個對象, 需要去調用一下 super.clone 這個方法來得到它。當你在執(zhí)行淺拷貝操作的時候, 意味著你只是在復制你的該類本身的對象而你并沒有在該類的屬性之中所包含的其他類對象的層面上進行拷貝動作。所謂深拷貝, 這個意思是指對包含類自己本身以及屬性類在內的所有類都進行一個完整的拷貝操作。把話說的再簡單一些, 其實就是淺拷貝操作后產生的那兩個對象里的屬性依然去指向同一個類, 而深拷貝則是讓它們全部都變得彼此獨立了。也就是說深拷貝這一行為連帶著把那些關聯(lián)關系也給一并拷貝了過來。我們可以把它簡單地理解為在深拷貝里面會存在那些數(shù)據類型中包含了類類型的變量這種情況, 這是因為在 java 這門語言里傳遞參數(shù)的形式是基于傳值方式來進行操作的。這五個方面, 其涉及的方法主要是這樣的:大家所知道的是, 這個方法屬于垃圾回收器運行機制中一個部分。這個方法是在垃圾回收器處理它相關聯(lián)的那些對象的時候被觸發(fā)的, 如果在執(zhí)行這個方法的運行期間發(fā)生了那些程序本身沒有辦法進行捕獲的異常的情況, 那么垃圾回收機制就會停止對這個特定對象的后續(xù)清理工作, 并且這種發(fā)生的異常情況將被系統(tǒng)直接忽略掉, 一直到下一次垃圾回收機制啟動并對這個仍然存在的對象進行清理操作的時候, 這個方法才會被重新調用一遍。請您看一下下邊給出的這幾個小例子。Java代碼public final class FinallyTest {// 重寫finalize()方法protected void finalize() throws Throwable {System.out.println(執(zhí)行了finalize()方法);}public static void main(String[] args) {FinallyTest ft new FinallyTest();ft null;System.gc();}}運行結果如下? 執(zhí)行了()方法在這個程序當中, 調用了屬于java.lang.這個類里面的gc()這個方法, 由此導致了垃圾回收GC操作被執(zhí)行。當垃圾回收器在處理ft這個對象的時候, 調用了該對象的某個方法, 正是由于這個原因, 所以我們才會看到上文提到的輸出結果。實際上, 調用.gc()和下面所寫的那一行代碼在效果上是一樣的:Java代碼.().gc();調用某個方法的作用, 說白了, 就是給垃圾收集器提個建議。意思是想讓垃圾收集器趕緊啟動起來, 好把那些沒用的對象清理出去, 從而釋放出占用的內存空間。不過, 垃圾收集器到底什么時候啟動, 這個并不是板上釘釘、必須馬上辦的事, 而是得由 JAVA虛擬機來拿主意決定。這就導致了這么一種情況: 在 JAVA虛擬機一直運行著直到它最終停止運行這段時間里, 有些對象的該方法可能連一次都沒有被運行過。那么問題來了, 究竟該怎么去保證每個對象的這個方法, 都能在 JAVA虛擬機徹底停止運行之前, 一定被調用成功? 答案就是, 我們可以去調用類的另一個方法。Java代碼這是一個函數(shù)聲明, 函數(shù)名為 void , 參數(shù)為 value , 大括號內有其他代碼。public static void runFinalizersOnExit(boolean value) {//other code}給這個方法傳入 true 這個值, 就可以保證當 Java 虛擬機停止運行的時候, 對象的 () 方法一定會被運行。不過遺憾的是, 這個方法是不安全的。它會導致有用的對象 () 被錯誤地調用。因此, 目前大家已經不贊成使用這種方法了。由于這個類屬于某種特定的類別, 所以所有的類都擁有這個方法, 并且該類的任意子類都可以對這一方法進行重寫操作, 在這個重寫的過程里面可以進行系統(tǒng)資源的釋放動作或者是執(zhí)行其他的一些清理工作, 例如關閉輸入流和輸出流等。六 wait()/()/()在一般情況下, 多個線程彼此之間是需要協(xié)調工作的。舉個具體的例子來講, 瀏覽器里負責進行圖片顯示的這樣一個線程, 它如果想要去執(zhí)行顯示圖片的具體任務, 那么就必須等待另一個下載線程, 這個下載線程得先把該張圖片給下載完成再說。倘若此時圖片還沒有全部都下載完畢的話, 那就可以選擇暫時性暫停, 等到相關任務徹底完成了之后, 再去發(fā)出“圖片已經準備充足, 能夠展示”這樣的通知, 緊接著再繼續(xù)往下執(zhí)行后續(xù)的操作。說白了, 上面的邏輯就是這樣的, 如果條件不滿足, 那就去等著, 什么時候條件滿足了呢, 那個正在等這個條件的線程, 就會被人叫醒。在Java語言里面, 這個法子能夠實現(xiàn), 是靠那個wait方法以及相關的等待機制來完成的, 并且這個等待的法子, 和鎖這個東西, 關系是非常非常緊密的。打個比方來說:(obj) { while(!) { obj.wait(); } obj.(); }synchronized(obj) {while(!condition) {obj.wait();}obj.doSomething();}當線程A獲取了obj鎖之后, 它發(fā)現(xiàn)當前條件不滿足情況, 所以沒辦法繼續(xù)執(zhí)行后續(xù)的處理步驟, 緊接著線程A就調用了wait()方法來進行等待操作。然后來看另一個線程B的情況, 如果在某個時段內, 線程B對某些特定的條件做出了更改動作, 使得原先那個讓線程A無法滿足的條件現(xiàn)在變得滿足了話, 那么這個時候就可以觸發(fā)機制來喚醒線程A:(obj)等于true, 然后調用obj的一個方法。synchronized(obj) {condition true;obj.notify();}有一個概念是大家需要加以關注的。在調用obj.wait()這個方法之前, 是一定要先得到obj這個對象上的鎖的, 所以, 相關的操作代碼必須是被包裹在針對obj對象的 代碼塊里面去執(zhí)行的。在線程A成功調用obj.wait這個方法之后, 線程A就把obj的鎖給交出來了, 如果沒有這一步, 線程B就沒法拿到obj的鎖, 那么線程B也就沒法在obj的大括號所包含的代碼段里面把線程A叫醒。等到obj.wait這個方法把結果返回回來的時候, 線程A還得再次去把obj的鎖給爭下來, 拿到了這把鎖之后, 它才能接著往下干活。如果A1以及A2和A3都處在了調用obj.wait()的狀態(tài)之中, 那么當B去調用()的時候, 它只能把A1、A2或者A3這三個當中的某一個給喚醒掉, 至于具體到底是哪一個被喚醒了, 這個要由JVM來最終決定。通過調用obj.方法可以一次性喚醒A1、A2和A3這三個線程, 不過若想繼續(xù)執(zhí)行緊隨obj.wait方法之后的后續(xù)代碼語句, 線程必須是成功獲取到obj對象鎖的那個線程, 正因如此, 在A1、A2與A3之中僅有其中任意一個線程才有資格獲得該對象鎖并把事情做完, 比方說假定是A1搶到了鎖, 那么其余的線程就都得等著, 等到A1把對obj對象鎖的使用權交出去之后, 它們才又接著往下走。當程序里的B去訪問那個obj對象的時候, 也就是在運行B調用了obj這個相關操作的時候, 此時B手里是正拿著obj這個鎖的, 所以, 雖然A1、A2還有A3這三個家伙已經被喚醒弄好了, 可是它們還是沒辦法拿到obj這把鎖來使用, 直到過了一陣子, 到了B退出了它當前占據的那一塊代碼范圍以后, 才松勁了把obj這塊鎖給放出去了, 這個時候, A1、A2和A3當中挑一個出來才有機會把這個鎖給抓住了然后繼續(xù)跑它的程序。