今天改代碼的時(shí)候,遇到一個(gè)很郁悶的問(wèn)題,J2me 程序運(yùn)行時(shí)拋出一個(gè)空指針異常,經(jīng)過(guò)反復(fù)研究,發(fā)現(xiàn)問(wèn)題所在,的確是自己的基礎(chǔ)知識(shí)不過(guò)關(guān)導(dǎo)致。
參考文章如下:http://www.jcwcn.com/html/Java/10_43_37_918.htm
在改普通例程變mvc架構(gòu)例程的過(guò)程中,學(xué)到了太多的東西,這些天的工作筆記和學(xué)習(xí)心得記敘著這一切。
簡(jiǎn)單說(shuō)明一下,源程序是個(gè)電話簿例程,就一個(gè)文件,所有的事務(wù)邏輯處理視圖都寫(xiě)在一起,我要做的工作就是將其分離開(kāi)來(lái),按照MVC架構(gòu)的模式重新改寫(xiě)。
源程序中有這樣一段,啟動(dòng)后顯示mainForm主菜單界面
public void startApp() {
mainForm();
}
public void mainForm() {
List l = new List("我的電話本", Choice.IMPLICIT);
l.append("查看所有電話", null);
l.append("新增電話記錄", null);
l.append("查找電話記錄", null);
l.append("退出電話本", null);
l.setCommandListener(this);
display.setCurrent(l);
}
現(xiàn)在我要把這個(gè)mainForm從中主程序分離出來(lái),單獨(dú)提出來(lái)寫(xiě)在ui的包中,不過(guò),出現(xiàn)了空指針異常
java.lang.NullPointerException
java.lang.NullPointerException
at com.wiser.mvctest.ui.UIController.setCurrent(+5)
at com.wiser.mvctest.ui.UIController.displayWelcome(+8)
at com.wiser.mvctest.ui.UIController.init(+16)
at com.wiser.mvctest.AddrBookMIDlet.startApp(+19)
at javax.microedition.midlet.MIDletProxy.startApp(+7)
at com.sun.midp.midlet.Scheduler.schedule(+270)
at com.sun.midp.main.Main.runLocalClass(+28)
at com.sun.midp.main.Main.main(+116)
單提出來(lái)的MainMenuForm文件代碼如下
package com.wiser.mvctest.ui;
import javax.microedition.lcdui.*;
import com.wiser.mvctest.ui.UIController;
import javax.microedition.lcdui.List;
public class MainMenuForm extends List implements CommandListener {
private UIController uicontroller;
public MainMenuForm(UIController uicontroller) {
super("我的電話本", Choice.IMPLICIT);// 調(diào)用父類(lèi)list的構(gòu)造方法
this.uicontroller = uicontroller;
this.append("查看所有電話", null);
this.append("新增電話記錄", null);
this.append("查找電話記錄", null);
this.append("退出電話本", null);
this.setCommandListener(this);
}
public void commandAction(Command c, Displayable s) {
if (c == List.SELECT_COMMAND) {
List temp = (List) s;
switch (temp.getSelectedIndex()) {
case 0: // 選擇0,則傳EVENT_ALL_LIST_FORM這個(gè)參數(shù)到handleEvent方法,查看所有電話
uicontroller.handleEvent(
UIController.EventID.EVENT_ALL_LIST_FORM, null);
break;
case 1:// 選擇1,則傳EVENT_NEW_RECORD_FORM這個(gè)參數(shù)到handleEvent方法,新增電話記錄
uicontroller.handleEvent(
UIController.EventID.EVENT_NEW_RECORD_FORM, null);
break;
case 2:// 選擇2,則傳EVENT_SEARCH_RECORD_FORM這個(gè)參數(shù)到handleEvent方法,查找電話記錄
uicontroller.handleEvent(
UIController.EventID.EVENT_SEARCH_RECORD_FORM, null);
break;
case 3:// 選擇3,則傳EVENT_EXIT_FORM這個(gè)參數(shù)到handleEvent方法,退出電話本
uicontroller.handleEvent(UIController.EventID.EVENT_EXIT_FORM,
null);
break;
default:
break;
}
}
}
}
UIController是我寫(xiě)的一個(gè)界面控制器,其中要求顯示MainMenuForm界面的源代碼如下
public void init() {
mainMenuForm = new MainMenuForm(this);
setCurrent(mainMenuForm);
}
初始化MainMenuForm后,將其傳入setCurrent。
那么很明顯上面的MainMenuForm界面代碼是沒(méi)有錯(cuò)誤的,而且,在異常里看,問(wèn)題應(yīng)該就出在UIController的setCurrent,那么這個(gè)空指針到底是為什么呢?在網(wǎng)上搜索了一下,發(fā)現(xiàn)一個(gè)人的學(xué)習(xí)筆記,他的問(wèn)題是構(gòu)造函數(shù)加了void的問(wèn)題,而我的構(gòu)造函數(shù)是正確的;再查看api,setCurrent要求的參數(shù)是setCurrent(Displayable dis),而里面的MainMenuForm也已經(jīng)初始化了,為什么還找不到呢?
這就是我當(dāng)時(shí)的想法,很混亂,迷惑,而實(shí)際上這和MainMenuForm沒(méi)有關(guān)系,空指針空的是當(dāng)前的界面對(duì)象,也就是程序最開(kāi)始什么界面都沒(méi)有,或者說(shuō)就是display這個(gè)對(duì)象是空的,那么如果display是空的,那他的方法setCurrent自然不能用,這才是原因所在,現(xiàn)在我在UIController的init方法中添加這樣一句
this.display = Display.getDisplay(addrbookmidlet); // addrbookmidlet在UIController構(gòu)造函數(shù)中得到
這樣就可以了。
問(wèn)題解決完了,對(duì)J2ME的理解又深了一步,并且對(duì)java的基礎(chǔ)知識(shí)也進(jìn)一步鞏固了。
待我理清思路再重新來(lái)看一下,現(xiàn)在繼續(xù)工作。