一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

別人經(jīng)驗--關(guān)于Object類理解(好)

 fanjj 2009-08-26
Java  雜談(三)
        這已經(jīng)筆者寫的第三篇Java雜記了,慶幸前兩篇一直得到論壇朋友們的支持鼓勵,還望大家繼續(xù)指正不足之處。筆者也一直渴望通過這樣方式清醒的自審,來尋找自己技術(shù)上的不足之處,希望和共同愛好Java的同仁們一起提高。
        前兩次分別講述了關(guān)于jvm、jdk、jre、collection、classLoader和一些Design  Pattern的自我理解。這次仍然不準(zhǔn)備開始過渡到j(luò)2ee中,因為覺得還有一些瑣碎的j2se的問題沒有總結(jié)完畢。
   
          1.  關(guān)于Object類理解
        大家都知道Object是所有Java類的基類,  意味著所有的Java類都會繼承了Object的11個方法。建議大家去看看Object的  11個成員函數(shù)的源代碼,就會知道默認(rèn)的實現(xiàn)方式。比如equals方法,默認(rèn)實現(xiàn)就是用"=="來比較,即直接比較內(nèi)存地址,返回true  或者  false。而toString()方法,返回的串組成方式是??
        "getClass().getName()  +  "@"  +  Integer.toHexString(hashCode())"
        其實不用我過多的解釋,大家都能看懂這個串的組成。接下來再看看hashCode():
        public  native  int  hashCode();
     
        由于是native方法,跟OS的處理方式相關(guān),源代碼里僅僅有一個聲明罷了。我們有興趣的話完全可以去深究它的hashCode到底是由OS怎么樣產(chǎn)生的呢?但筆者建議最重要的還是先記住使用它的幾條原則吧!首先如果equals()方法相同的對象具有相通的hashCode,但equals  ()對象不相通的時候并不保證hashCode()方法返回不同的整數(shù)。而且下一次運行同一個程序,同一個對象未必還是當(dāng)初的那個hashCode()  哦。
        其余的方法呢?nofigy()、notifyAll()、clone()、wait()都是native方法的,說明依賴于操作系統(tǒng)的實現(xiàn)。最后一個有趣的方法是finalize(),類似C++的析構(gòu)函數(shù),簽名是protected,證明只有繼承擴(kuò)展了才能使用,方法體是空的,默示什么也不做。它的作用據(jù)筆者的了解僅僅是通知JVM此對象不再使用,隨時可以被銷毀,而實際的銷毀權(quán)還是在于虛擬機(jī)手上。那么它真的什么也不做麼?未必,實際上如果是線程對象它會導(dǎo)致在一定范圍內(nèi)該線程的優(yōu)先級別提高,導(dǎo)致更快的被銷毀來節(jié)約內(nèi)存提高性能。其實從常理來說,我們也可以大概這樣猜測出jvm做法的目的。

        2.  關(guān)于重載hashCode()與Collection框架的關(guān)系
筆者曾經(jīng)聽一位搞Java培訓(xùn)多年的前輩說在他看來hashCode方法沒有任何意義,僅僅是為了配合證明具有同樣的hashCode會導(dǎo)致equals  方法相等而存在的。連有的前輩都犯這樣的錯誤,其實說明它還是滿容易被忽略的。那么hashCode()方法到底做什么用?
     
        學(xué)過數(shù)據(jù)結(jié)構(gòu)的課程大家都會知道有一種結(jié)構(gòu)叫hash  table,目的是通過給每個對象分配一個唯一的索引來提高查詢的效率。那么Java也不會肆意扭曲改變這個概念,所以hashCode唯一的作用就是為支持?jǐn)?shù)據(jù)結(jié)構(gòu)中的哈希表結(jié)構(gòu)而存在的,換句話說,也就是只有用到集合框架的  Hashtable、HashMap、HashSet的時候,才需要重載hashCode()方法,
這樣才能使得我們能人為的去控制在哈希結(jié)構(gòu)中索引是否相等。筆者舉一個例子:
        曾經(jīng)為了寫一個求解類程序,需要隨機(jī)列出1,2,3,4組成的不同排列組合,所以筆者寫了一個數(shù)組類用int[]來存組合結(jié)果,然后把隨機(jī)產(chǎn)生的組合加入一個HashSet中,就是想利用HashSet不包括重復(fù)元素的特點。可是HashSet怎么判斷是不是重復(fù)的元素呢?當(dāng)然是通過  hashCode()返回的結(jié)果是否相等來判斷啦,可做一下這個實驗:
        int[]  A  =  {1,2,3,4};
        int[]  B  =  {1,2,3,4};
        System.out.println(A.hashCode());
        System.out.println(B.hashCode());

        這明明是同一種組合,卻是不同的hashCode,加入Set的時候會被當(dāng)成不同的對象。這個時候我們就需要自己來重寫hashCode()方法了,如何寫呢?其實也是基于原始的hashCode(),畢竟那是操作系統(tǒng)的實現(xiàn),  找到相通對象唯一的標(biāo)識,實現(xiàn)方式很多,筆者的實現(xiàn)方式是:
        首先重寫了toString()方法:
        return    A[0]“+”  A[1]“+”  A[2]“+”  A[3];  //顯示上比較直觀
        然后利用toString()來計算hashCode():
        return    this.toString().hashCode();
        這樣上述A和B返回的就都是”1234”,在測試toString().hashCode(),由于String在內(nèi)存中的副本是一樣的,”1234”.hashCode()返回的一定是相同的結(jié)果。

        說到這,相信大家能理解得比我更好,今后千萬不要再誤解hashCode()方法的作用。

        3.  關(guān)于Class類的成員函數(shù)與Java反射機(jī)制
        很早剛接觸Java就聽很多老師說過Java的動態(tài)運行時機(jī)制、反射機(jī)制等。確實它們都是Java的顯著特點,運行時加載筆者在第一篇介紹過了,現(xiàn)在想講講反射機(jī)制。在Java中,主要是通過java.lang包中的Class類和Method類來實現(xiàn)內(nèi)存反射機(jī)制的。
        熟悉C++的人一定知道下面這樣在C++中是做不到的:  運行時以字符串參數(shù)傳遞一個類名,就可以得到這個類的所有信息,包括它所有的方法,和方法的詳細(xì)信息。還可以實例化一個對象,并通過查到的方法名來調(diào)用該對象的任何方法。這是因為Java的類在內(nèi)存中除了C++中也有的靜態(tài)動態(tài)數(shù)據(jù)區(qū)之外,還包括一份對類自身的描述,也正是通過這描述中的信息,才能幫助我們才運行時讀取里面的內(nèi)容,得到需要加載目標(biāo)類的所有信息,從而實現(xiàn)反射機(jī)制。大家有沒有想過當(dāng)我們需要得到一個JavaBean的實例的時候,怎么知道它有哪些屬性呢?再明顯簡單不過的例子就是自己寫一個JavaBean的解析器:

        a.  通過Class.forName(“Bean的類名”)得到Class對象,例如叫ABeanClass
        b.  通過ABeanClass的getMethods()方法,得到Method[]對象
        c.  按照規(guī)范所有g(shù)et方法名后的單詞就代表著該Bean的一個屬性
        d.  當(dāng)已經(jīng)知道一個方法名,可以調(diào)用newInstance()得到一個實例,然后通過invoke()方法將方法的名字和方法需要用的參數(shù)傳遞進(jìn)去,就可以動態(tài)調(diào)用此方法。

        當(dāng)然還有更復(fù)雜的應(yīng)用,這里就不贅述,大家可以參考Class類和Method類的方法。

        4.  坦言Synchronize的本質(zhì)
        Synchronize大家都知道是同步、加鎖的意思,其實它的本質(zhì)遠(yuǎn)沒有大家想得那么復(fù)雜。聲明Synchronize的方法被調(diào)用的時候,鎖其實是加載對象上,當(dāng)然如果是靜態(tài)類則是加在類上的鎖,調(diào)用結(jié)束鎖被解除。它的實現(xiàn)原理很簡單,僅僅是不讓第二把鎖再次被加在同一個對象或類上,僅此而已。一個簡單的例子足以說明問題:
        class  A{
synchronized  void  f(){}
void  g(){}
        }

        當(dāng)A的一個對象a被第一個線程調(diào)用其f()方法的時候,第二個線程不能調(diào)用a的synchronized方法例如f(),因為那是在試圖在對象上加第二把鎖。但調(diào)用g()卻是可以的,因為并沒有在同一對象上加兩把鎖的行為產(chǎn)生。
        這樣大家能理解了麼?明白它的原理能更好的幫助大家設(shè)計同步機(jī)制,不要濫用加鎖。

        PS:下篇筆者計劃開始對J2ee接觸到的各個方面來進(jìn)行總結(jié),談?wù)勛约旱慕?jīng)驗和想法。希望大家還能一如既往的支持筆者寫下去,指正不足之處。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    精品al亚洲麻豆一区| 在线视频免费看你懂的| 国产伦精品一区二区三区高清版| 午夜福利大片亚洲一区| 中文字幕中文字幕在线十八区| 日韩精品视频一二三区| 91播色在线免费播放| 伊人网免费在线观看高清版| 亚洲人妻av中文字幕| 亚洲天堂精品一区二区| 亚洲视频一级二级三级| 老司机亚洲精品一区二区| 亚洲视频一区二区久久久| 色偷偷偷拍视频在线观看| 亚洲欧美日韩网友自拍| 国产精品欧美在线观看| 冬爱琴音一区二区中文字幕| 国产精品成人一区二区在线| 久久精品国产熟女精品| 午夜色午夜视频之日本| 中文字幕禁断介一区二区| 国产原创激情一区二区三区| 开心激情网 激情五月天| 亚洲中文字幕综合网在线| 高清国产日韩欧美熟女| 国产欧洲亚洲日产一区二区| 亚洲精品福利入口在线| 欧美不卡一区二区在线视频| 国产又粗又猛又长又大| 日韩专区欧美中文字幕| 日本99精品在线观看| 福利专区 久久精品午夜| 麻豆剧果冻传媒一二三区| 国产一二三区不卡视频| 亚洲天堂精品在线视频| 中文字幕乱码一区二区三区四区| 欧美亚洲综合另类色妞| 草草视频精品在线观看| 国产不卡在线免费观看视频| 亚洲欧美日本成人在线| 丰满少妇被粗大猛烈进出视频|