與其說是學J2ME的經驗,倒不如說是類C++語言的一點注意事項,之所以這么說,是因為這個問題是在學J2ME時候發現的,整整折騰了我一天,雖然只是一點小的失誤,但是直接后果是程序不斷異常,所以我把它寫出來,一方面提醒自己,學知識不能淺嘗輒止,而應該多問為什么,不僅知其然還要知所以然,另一方面也告訴更多像我這樣初學的朋友不要犯相同的錯誤。
下面請看一段代碼:
/* * ImageItemDemo.java * * Created on 2005年7月24日, 下午1:45 */
import javax.microedition.midlet.*; import javax.microedition.lcdui.*;
/** * * @author mark * @version */ public class ImageItemDemo extends MIDlet implements CommandListener{ private Command exitCommand=new Command("Exit",Command.EXIT,1); private Form mainform;; private ImageItem img1,img2; public void ImageItemDemo(){ mainform=new Form("ImageItem Test"); mainform.append("顯示各種ImageItem"); mainform.addCommand(exitCommand); mainform.setCommandListener(this);
} public void startApp() { try{ img1=new ImageItem("默認圖像控件", Image.createImage("/Image.png"), Item.LAYOUT_DEFAULT, "第一張圖片"); img2=new ImageItem("默認圖像控件", Image.createImage("/Image.png"), Item.LAYOUT_2|Item.LAYOUT_EXPAND|Item.LAYOUT_NEWLINE_BEFORE, "第二張圖片"); }catch(Exception err){ System.out.println("can not load...."); }
mainform.append(img1); mainform.append(img2); Display.getDisplay(this).setCurrent(mainform); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c,Displayable d){ if(c==exitCommand){ destroyApp(false); notifyDestroyed(); } } }
這是一個ImageItemt的演示程序,我在實現的前提下加了一點東西導致它異常,異常如下:
startApp threw an Exception java.lang.NullPointerException java.lang.NullPointerException at ImageItemDemo.startApp(+64) 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)
能找到異常原因嗎?
首先確定是由startApp拋出空指針異常,其中用到的對象主要有兩個,mainform和img1、img2,然而image載入拋出的應該可由catch(Exception err)捕獲到,所以基本可以確定是mainform產生的異常,可是問題來了,mainform我已經在構造函數里面實例化了,而且也是類的成員變量,應該隨對象存在,可是為什么會異常呢?
百思不得其解。。。。
于是把ImageItemDemo()里的代碼移到startApp()里面,發現居然實現了,可以確定,就是沒有實例化mainform。原因何在?難道是J2ME要先執行startApp才執行構造函數??答案是否定的。startApp()只是程序運行的切入點,對象和類的構造依然還是由構造函數完成。一個提示,那真的是構造函數嗎?
一個很明顯但是很容易被忽略的錯誤, public void ImageItemDemo(),它不是構造函數,甚至連構造函數的重載都不是,理由?限制了void類型。c++學了快1年了,確實沒有想過也沒有注意過這個問題,直接后果就是這樣,類在構造時候不會執行它,那么其中的mainform自然不會被實例化,而依然只是一個引用,何以談的上操作?
改的方法很容易,把void去掉就可以了,就這么一個簡單的問題,耗了我一天,最大的感覺就是自己學的不夠深,對理論觀點依舊不夠明確,所以寫下它引以為戒。
|