青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

chenglong7997

java重載重寫陷阱

  看《重構(gòu)(注釋版)》中“封裝集合(Encapsulate Collection)”一節(jié)時(shí),由于該重構(gòu)手法對于不同的 Java 版本會(huì)有相對應(yīng)不同的處理方式,于是注釋者在旁邊給出提示:Java 2 中的新 Collections API 主要是由《Java 解惑》、《Effective Java》這兩本書的作者開發(fā)改進(jìn)的。我想,這可真是一個(gè)大消息,Java 類庫的開發(fā)者所寫的書一定得看,開發(fā)者肯定深入探尋過 Java 內(nèi)部機(jī)制,說不定能從書中獲得未知的知識點(diǎn)呢。

好在我記得自己電腦里下載過《Java 解惑(中文版)》的清晰電子版,于是改變路線,看起這本書來了。真是不看不知道,一看嚇一跳!里面有 95 個(gè) Java 謎題,一點(diǎn)點(diǎn)地看了之后,我是既慚愧又興奮,因?yàn)槔锩娴念}真的是“莫名其妙”,直白點(diǎn)就是:十有八九是想都想不出來的,⊙﹏⊙b…想要真正掌握 Java ,我覺得《Java 解惑》是不得不看的。大多謎題可謂是前所未見的炸彈,一不小心就 over 了。

快點(diǎn)切入正題,如文章標(biāo)題所示,我從《Java 解惑》中似乎認(rèn)識到了幾個(gè)名詞,之所以用似乎修飾,因?yàn)橹剌d、重寫、隱藏這幾個(gè)接觸過了,而遮蔽、遮掩或許是見過但也就忘光了。就整理一下文中的一些與此相關(guān)的 Java 謎題用自己的理解描述一下吧。

重載(overload):同一個(gè)類中名字相同但參數(shù)列表不同的多個(gè)方法之間的關(guān)系。

關(guān)于重載,是我們比較熟悉的了,最常見的就是運(yùn)用在類的多個(gè)構(gòu)造函數(shù)中,看一下 Java 幫助文檔,就可以明白這一情況了。而在《Java 解惑》中,作者給出了下面一個(gè)謎題:

  1. public class Confusing {   
  2.       
  3.     private Confusing(Object o) {   
  4.         System.out.println("Object");   
  5.     }   
  6.       
  7.     private Confusing(double[] dArray) {   
  8.         System.out.println("double array");   
  9.     }   
  10.       
  11.     public static void main(String[] args) {   
  12.         new Confusing(null);   
  13.     }   
  14. }  

問此時(shí) main() 中將會(huì)輸出什么?初初一看,并沒有多分析就覺得應(yīng)該是輸出“Object”,雖然Java中的數(shù)組實(shí)際上也是引用類型,但畢竟Object 是所有類的最終父類,而且目前 JDK 就連參數(shù)中的基本數(shù)據(jù)類型變量也可以被自動(dòng)想上轉(zhuǎn)型成包裝類而成為 Object 的子類。于是我保守一點(diǎn)地就認(rèn)為參數(shù) null 應(yīng)該是匹配到 Object 那個(gè)重載方法去了。

可是這答案是錯(cuò)的,JVM 對于重載方法的解析是這樣的:先找出方法名匹配的所有可能的方法;然后根據(jù)傳進(jìn)來的形參再次篩選出可能的重載方法;最后才是在這些方法中匹配到一個(gè)最精確的一個(gè)方法。于是,上面的那個(gè)謎題就變成確定哪一個(gè)才是最精確這一點(diǎn)子上了。

而關(guān)于如何判斷最精確,有這樣的機(jī)制:如果某個(gè)重載方法能夠接收所有傳遞給另一個(gè)重載方法的實(shí)參類型,那么對于參數(shù)列表來看,顯然后者至少是前者的子集,當(dāng)然也就更精確了。

回到謎題上來,Confusing(Object)可以接受任何傳遞給 Confusing(double[ ])的參數(shù)(任何數(shù)組引用最終能夠都是 Object 對象),因此 main() 中的 null 應(yīng)該是被 JVM 匹配到 Confusing(double[ ]) 中,也就有了與我所認(rèn)為的結(jié)果相反的輸出了。

小結(jié):這個(gè)謎題表明了我們在寫重載方法時(shí),最好是明確地區(qū)分出各個(gè)方法中的參數(shù)列表,不要讓彼此之間有互相包含、模糊不清的關(guān)系。雖然重載是為了在相同名字的方法中傳入實(shí)參,由 JVM 動(dòng)態(tài)解析選擇合適的方法,但有時(shí)也很容易陷入這種方便背后所帶來的地雷區(qū)當(dāng)中。其中一種可行的辦法就是,提供不同的方法名。但是構(gòu)造函數(shù)的名字一定得相同的啊?

實(shí)際上,在《重構(gòu)與模式》第六章中,作者用他自身的項(xiàng)目經(jīng)驗(yàn)對“創(chuàng)建”這一話題展開了講解,就算是構(gòu)造函數(shù),也有很好的重構(gòu)手法將其清晰地區(qū)分開來,不使用重載而是用不同名稱的方法,將原本需要重載的構(gòu)造函數(shù)委托給具有最大完整參數(shù)列表的私有構(gòu)造函數(shù)中。又是一本經(jīng)典,值得看哦…

 

重寫(override):父類中的實(shí)例方法被其子類重新實(shí)現(xiàn)。既然是實(shí)例方法,那就是非 static 修飾的了,否則就是 static 靜態(tài)方法了,那叫做類方法。在我看來,正是重寫這一機(jī)制的存在,才為多態(tài)機(jī)制提供了基礎(chǔ)。或許 implements (實(shí)現(xiàn))一個(gè) interface (接口)中所聲明的方法也能成為重寫,因?yàn)?interface 的一部分存在原因也是為了多態(tài)。

對于重寫,在《Java 解惑》中有下面這個(gè)謎題讓我明白:絕對不能在構(gòu)造函數(shù)中調(diào)用可能會(huì)被子類重寫的方法。

  1. class Point {  
  2.     protected final int x, y;  
  3.     private final String name;  
  4.       
  5.     Point(int x, int y) {  
  6.         this.x = x;  
  7.         this.y = y;  
  8.         name = makeName();  
  9.     }  
  10.  
  11.     protected String makeName() {  
  12.         return "[" + x + "," + y + "]";  
  13.     }  
  14.       
  15.     public final String toString() {  
  16.         return name;  
  17.     }  
  18. }  
  19.  
  20. public class ColorPoint extends Point {  
  21.     private final String color;  
  22.       
  23.     ColorPoint(int x, int y, String color) {  
  24.         super(x, y);  
  25.         this.color = color;  
  26.     }  
  27.       
  28.     protected String makeName() {  
  29.        return super.makeName() + ":" + color;  
  30.     }  
  31.       
  32.     public static void main(String[] args) {  
  33.         System.out.println(new ColorPoint(4, 2, "purple"));  
  34.     }  

此時(shí)程序運(yùn)行結(jié)果并不是我們所想的 [4,2]:purple ,而是 [4,2]:null 。為什么會(huì)這樣?看看下面用流程標(biāo)號注釋過的代碼,就能理解了。

  1. class Point {  
  2.     protected final int x, y;  
  3.     private final String name;  
  4.  
  5.     Point(int x, int y) {  
  6.         this.x = x;  
  7.         this.y = y;  
  8.         name = makeName();// 3. 由于被子類重寫過的makeName()  
  9.     }  
  10.  
  11.     protected String makeName() {  
  12.         return "[" + x + "," + y + "]";  
  13.     }  
  14.       
  15.     public final String toString() {  
  16.         return name;  
  17.     }  
  18. }  
  19.  
  20. public class ColorPoint extends Point {  
  21.     private final String color;  
  22.  
  23.     ColorPoint(int x, int y, String color) {  
  24.         super(x, y); // 2. 調(diào)用Point父類構(gòu)造函數(shù)  
  25.         this.color = color; // 5. 初始化 color ,可是已經(jīng)太晚了...  
  26.     }  
  27.  
  28.     protected String makeName() {  
  29.         // 4. 問題來了:它在子類構(gòu)造函數(shù)之前調(diào)用了  
  30.         // 而此時(shí)的 color 是 null 的啊!!!  
  31.         return super.makeName() + ":" + color;  
  32.     }  
  33.  
  34.     public static void main(String[] args) {  
  35.         // 1. 調(diào)用ColorPoint子類構(gòu)造函數(shù)  
  36.         System.out.println(new ColorPoint(4, 2, "purple"));  
  37.     }  

思路很清晰了,ColorPoint 子類中的構(gòu)造函數(shù)中的 this.color = color; 還未被執(zhí)行到就將 null 作為 String color 的值了。正是因?yàn)檫@種來來回回的調(diào)用使得程序變得不正常了,在我看來,有那么一點(diǎn)類似于“回調(diào)”的意思。

要去除這種代碼結(jié)構(gòu)的不合理,最好還是把 Point 父類構(gòu)造函數(shù)中調(diào)用 makeName() 方法一句去掉,然后在 toString  中判斷并調(diào)用 makeName() 來為 name 初始化,如下:

小結(jié):重寫對于多態(tài)固然重要,但是設(shè)計(jì)出不正確的代碼結(jié)構(gòu)的話,原本想要的多態(tài)就會(huì)被扭曲甚至造成反效果。于是,絕對不要在構(gòu)造函數(shù)中調(diào)用可能會(huì)被子類重寫的方法。

 好像文字太多的文章看了容易使人暈乎乎的,啰啰嗦嗦、模模糊糊地才寫了兩個(gè)詞兒,還是分開來寫吧。其實(shí),看了一部分《Java 解惑》才明白還有好多好多 Java 里面該注意的要點(diǎn)。要想在適當(dāng)?shù)臅r(shí)候辨清各種語法上、機(jī)制上的知識點(diǎn),難啊!

記得高中語文課上讀過一片抒情的散文,標(biāo)題為“哦——香雪!”而我看了《Java 解惑》,想說“噢——Java!”~~~~(>_<)~~~~

總結(jié):

1、在我們編程領(lǐng)域,好書真的是一大把,就看自己有沒時(shí)間、有沒策略地去吸收了;

2、有時(shí)候看好書時(shí)留意作者對其他書籍的“友情鏈接”,或者出版社推薦的相關(guān)書籍,這樣就能夠免去自己慢慢搜尋好書的過程了,O(∩_∩)O哈!

本文出自 “螞蟻” 博客,請務(wù)必保留此出處http://haolloyin.blog.51cto.com/1177454/372691

posted on 2012-04-11 13:59 Snape 閱讀(318) 評論(0)  編輯 收藏 引用 所屬分類: Java

導(dǎo)航

<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

統(tǒng)計(jì)

常用鏈接

留言簿

隨筆分類

隨筆檔案

文章分類

文章檔案

my

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美在线视频免费观看| 午夜精品成人在线视频| 久久久www成人免费毛片麻豆| 亚洲免费观看在线视频| 欧美日韩亚洲一区二区| 亚洲免费在线播放| 欧美亚洲综合久久| 亚洲成在线观看| 亚洲乱码久久| 国产日韩欧美黄色| 久久先锋影音| 欧美精品一区三区在线观看| 亚洲小说区图片区| 久久精品观看| 亚洲美女精品一区| 亚洲欧美日韩综合aⅴ视频| 激情成人亚洲| 日韩视频一区二区在线观看 | 免费视频一区二区三区在线观看| 亚洲精品日韩在线观看| 亚洲网站在线观看| 亚洲国产精品视频| 亚洲一区免费网站| 亚洲美女免费精品视频在线观看| 亚洲一区中文字幕在线观看| 亚洲国产精品va在线看黑人动漫| 日韩一级二级三级| 伊大人香蕉综合8在线视| 99riav久久精品riav| 影音先锋亚洲电影| 一区二区国产在线观看| 有码中文亚洲精品| 午夜国产一区| 亚洲一区二区三区精品视频| 久久中文精品| 久久精品免费播放| 国产精品久久久久999| 欧美黄色精品| 黄色成人小视频| 亚洲男人的天堂在线aⅴ视频| 日韩一级成人av| 久久米奇亚洲| 久久久之久亚州精品露出| 国产精品久久国产精品99gif| 亚洲福利久久| 国内精品久久久久久久影视麻豆| 在线视频欧美日韩| 亚洲免费播放| 欧美精品高清视频| 欧美国产一区二区在线观看| 国模精品娜娜一二三区| 午夜精品www| 欧美一区在线视频| 国产欧美日本一区视频| 中文在线资源观看网站视频免费不卡 | 亚洲国产高清在线| 亚洲电影下载| 久久精品免视看| 久久久久久久999精品视频| 国产精品一区二区三区乱码| 亚洲最新视频在线播放| 亚洲五月婷婷| 国产精品高清在线| 亚洲在线中文字幕| 亚洲欧美日本伦理| 国产精品入口夜色视频大尺度| 中国女人久久久| 亚洲欧美国产77777| 国产精品美女黄网| 午夜免费电影一区在线观看| 欧美在线免费一级片| 国产农村妇女毛片精品久久莱园子 | 一区二区三区四区国产| 欧美激情视频给我| 一区二区欧美视频| 欧美在线视频播放| 在线观看欧美黄色| 女人色偷偷aa久久天堂| 亚洲精品在线免费观看视频| 亚洲一区二区三区乱码aⅴ蜜桃女| 欧美日韩妖精视频| 性高湖久久久久久久久| 欧美成人亚洲成人日韩成人| 亚洲精品视频在线| 国产精品视频xxx| 欧美一区深夜视频| 亚洲国产精品成人一区二区| 亚洲午夜未删减在线观看| 国产精品一区二区欧美| 久久夜色精品国产欧美乱| 亚洲精品无人区| 欧美综合二区| 亚洲精品一区二区在线| 国产精品高潮视频| 久久伊伊香蕉| 亚洲天天影视| 欧美成人午夜| 亚洲欧美综合精品久久成人| 在线欧美福利| 国产精品观看| 欧美成人精品h版在线观看| 亚洲视频视频在线| 欧美激情视频一区二区三区在线播放 | 欧美国产日产韩国视频| 一本色道久久综合亚洲精品小说| 国产精品综合色区在线观看| 暖暖成人免费视频| 欧美一区二区免费视频| 亚洲日本电影在线| 老司机67194精品线观看| 亚洲一区免费网站| 亚洲精选中文字幕| 红桃视频国产精品| 国产精品丝袜久久久久久app | 亚洲精品久久久久久下一站| 久久高清一区| 亚洲校园激情| 亚洲免费观看在线观看| 国产日韩精品在线观看| 欧美日一区二区在线观看 | 欧美亚洲视频一区二区| 一区二区免费在线播放| 91久久久久久| 欧美国产视频一区二区| 久热成人在线视频| 久久成人资源| 欧美一区二区高清| 亚洲午夜一区二区三区| 日韩一区二区免费高清| 亚洲欧洲一区二区在线播放| 红桃视频欧美| 樱桃国产成人精品视频| 国内成+人亚洲| 国产专区欧美专区| 国产一区二区三区四区| 国产一区二区三区精品久久久| 国产精品电影观看| 国产精品黄视频| 国产精品午夜国产小视频| 国产精品久久久99| 国产精品私人影院| 国产精品永久免费在线| 国产精品一区二区三区久久久| 国产精品久久久久99| 国产精品久久久久久久久搜平片| 欧美视频在线观看 亚洲欧| 欧美日韩在线另类| 欧美午夜视频在线| 国产精品毛片一区二区三区| 国产精品久久久久影院色老大 | 欧美日韩国产影院| 国产精品久久精品日日| 国产欧美日韩麻豆91| 国产一区二区三区久久久| 在线看欧美视频| 99re在线精品| 午夜精彩国产免费不卡不顿大片| 午夜欧美不卡精品aaaaa| 久久精品视频在线| 欧美成人免费小视频| 亚洲毛片网站| 亚洲欧美日韩在线观看a三区| 久久成人免费网| 欧美高清在线一区| 国产精品久久久久国产精品日日 | 另类尿喷潮videofree| 欧美二区在线播放| 国产精品久久综合| 在线观看一区| 亚洲免费在线观看| 免费不卡在线观看av| 日韩视频―中文字幕| 欧美在线观看一区| 欧美国产日韩一二三区| 国产精品性做久久久久久| 亚洲大片精品永久免费| 亚洲视频1区2区| 免费高清在线一区| 一区二区三区四区五区视频| 久久精品国产99国产精品澳门| 欧美黄色日本| 精东粉嫩av免费一区二区三区| 99精品视频免费观看视频| 欧美制服丝袜第一页| 亚洲欧洲精品一区二区三区| 亚洲女女做受ⅹxx高潮| 欧美顶级大胆免费视频| 国产一区二区在线观看免费播放 | 国产一区 二区 三区一级| 一本大道久久a久久精二百| 久久精品人人做人人爽| 亚洲日本视频| 美女黄毛**国产精品啪啪| 国产精品日韩电影| av成人国产| 欧美成黄导航| 久久久久成人精品免费播放动漫| 欧美深夜福利| av不卡在线观看| 亚洲国产小视频在线观看|