BlueIce |
|
|||
藍(lán)色的Java,冰色的BillQian |
日歷
統(tǒng)計(jì)
導(dǎo)航常用鏈接留言簿(2)隨筆檔案相冊(cè)搜索最新評(píng)論
閱讀排行榜評(píng)論排行榜 |
今天在網(wǎng)上看到一篇文章,感覺很好,它講到的是關(guān)于構(gòu)造函數(shù)的作用以及類的構(gòu)造問題,而這是初學(xué)者經(jīng)常會(huì)犯甚至是有經(jīng)驗(yàn)的程序員偶爾也會(huì)犯的錯(cuò)誤,在此我舉例總結(jié)一下,請(qǐng)看下面這段代碼:
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 這個(gè)類在有的代碼中工作得很好,但一個(gè)同事在使用時(shí),程序卻擲出了一個(gè)NullPointerException違例!經(jīng)過比較,找出了工作正常和不正常的程序的細(xì)微差別,代碼片斷分別如下: 一、工作正常的代碼: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 二、工作不正常的代碼: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 你看出來兩段代碼之間的差別了嗎?對(duì)了,兩者的差別僅僅在于類變量jTextFieldName的初始化時(shí)間。經(jīng)過跟蹤,發(fā)現(xiàn)在執(zhí)行 panel.add(jTextFieldName)語句之時(shí),jTextFieldName確實(shí)是空值. 當(dāng)程序創(chuàng)建一個(gè)ChildDlg2的實(shí)例時(shí),根據(jù)super(null,?“Title”)語句,首先執(zhí)行其父類BaseDlg的構(gòu)造方法;在BaseDlg的構(gòu)造方法中調(diào)用了createClientPanel()方法,這個(gè)方法是抽象方法并且被子類ChildDlg2實(shí)現(xiàn)了,因此,實(shí)際調(diào)用的方法是ChildDlg2中的createClientPanel()方法(因?yàn)镴ava里面采用“動(dòng)態(tài)綁定”來綁定所有非final的方法);createClientPanel()方法使用了ChildDlg2類的實(shí)例變量jTextFieldName,而此時(shí)ChildDlg2的變量初始化過程尚未進(jìn)行,jTextFieldName是null值!所以,ChildDlg2的構(gòu)造過程擲出一個(gè)NullPointerException也就不足為奇了。 再來看ChildDlg1,它的jTextFieldName的初始化代碼寫在了createClientPanel()方法內(nèi)部的開始處,這樣它就能保證在使用之前得到正確的初始化,因此這段代碼工作正常。 解決問題的兩種方式: 通過上面的分析過程可以看出,要排除故障,最簡單的方法就是要求項(xiàng)目組成員在繼承使用BaseDlg類,實(shí)現(xiàn)createClientPanel()方法時(shí),凡方法內(nèi)部要使用的變量必須首先正確初始化,就象ChildDlg1一樣。然而,把類變量放在類方法內(nèi)初始化是一種很不好的設(shè)計(jì)行為,它最適合的地方就是在變量定義塊和構(gòu)造方法中。 在本文的實(shí)例中,引發(fā)錯(cuò)誤的實(shí)質(zhì)并不在ChildDlg2上,而在其父類BaseDlg上,是它在自己的構(gòu)造方法中不適當(dāng)?shù)卣{(diào)用了一個(gè)待實(shí)現(xiàn)的抽象方法。 從概念上講,構(gòu)造方法的職責(zé)是正確初始化類變量,讓對(duì)象進(jìn)入可用狀態(tài)。而BaseDlg卻賦給了構(gòu)造方法額外的職責(zé)。 本文實(shí)例的更好的解決方法是修改BaseDlg類: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 新的BaseDlg類增加了一個(gè)initGUI()方法,程序員可以這樣使用這個(gè)類: ![]() ![]() ![]() ![]() 總結(jié): 類的構(gòu)造方法的基本目的是正確初始化類變量,不要賦予它過多的職責(zé)。 設(shè)計(jì)類構(gòu)造方法的基本規(guī)則是:用盡可能簡單的方法使對(duì)象進(jìn)入就緒狀態(tài);如果可能,避免調(diào)用任何方法。在構(gòu)造方法內(nèi)唯一能安全調(diào)用的是基類中具有final屬性的方法或者private方法(private方法會(huì)被編譯器自動(dòng)設(shè)置final屬性)。final的方法因?yàn)椴荒鼙蛔宇惛采w,所以不會(huì)產(chǎn)生問題。
評(píng)論:
|
![]() |
|
Copyright © BillQian | Powered by: 博客園 模板提供:滬江博客 |