首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME 新手慘痛教訓:構造函數誤加 void 導致 NPE 的一天

     編輯:J2ME

前言

這不只是 J2ME 經驗,更是類 C++ 語言基礎的血淚教訓。一個 void 關鍵字,讓構造函數變成普通方法,導致成員變量未初始化,程序拋出 NullPointerException,我足足除錯了一整天。記錄下來,警醒自己與同路人。

問題代碼

public class ImageItemDemo extends MIDlet {
    private Form mainForm;
    private ImageItem img1, img2;

    // 錯誤:加了 void,這不是構造函數!
    public void ImageItemDemo() {  
        mainForm = new Form("Demo");
        try {
            img1 = new ImageItem(...);
            img2 = new ImageItem(...);
        } catch (Exception e) { ... }
        mainForm.append(img1);
        mainForm.append(img2);
    }

    protected void startApp() {
        Display.getDisplay(this).setCurrent(mainForm); // NPE!mainForm 為 null
    }
    // ...
}

異常堆疊

startApp threw an Exception java.lang.NullPointerException
    at ImageItemDemo.startApp(+64)
    ...

錯誤分析

  1. startApp 拋出 NPE,涉及對象:mainForm、img1、img2。
  2. 圖片載入在 try-catch 中,異常會被捕獲,排除 img1/2。
  3. mainForm 已在類中聲明,並在「構造函數」中實例化,為何仍為 null?

關鍵發現:那不是構造函數!

構造函數不能有返回類型,甚至不能有 void。

  • public void ImageItemDemo() 是一個普通方法,名稱恰好與類同名。
  • JVM 創建對象時只會自動調用真正的構造函數(無返回類型、同名方法)。
  • 此普通方法從未被調用,mainForm 自然保持默認值 null。

修正方法

// 移除 void,變回真正的構造函數
public ImageItemDemo() {
    mainForm = new Form("Demo");
    // ...
}

深度反思

  • C++ 寫了一年,卻忽略了「構造函數無返回類型」這條鐵律。
  • J2ME MIDlet 生命週期:startApp 是入口點,但對象構造早於 startApp 完成。
  • 「知其然更要知其所以然」——基礎不牢,地動山搖。

給初學者的建議

  1. IDE 會對誤加返回類型的「偽構造函數」給出警告(如「Method has same name as class」),請務必重視警告。
  2. 遇到 NPE,先檢查成員變量是否真正在構造函數/初始化塊中賦值。
  3. 多問幾個「為什麼」,少複製貼上。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved