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

Java new 關鍵字深度解析:對象創建四步曲與單例模式最佳實踐

     編輯:Java 綜合教學

new 做了什麼?四步驟全解析

以 new MyDate(22, 7, 1964) 為例:

  1. 分配內存:在堆中劃分一塊區域存放 MyDate 實例數據。
  2. 默認初始化:字段賦零值(0/null/false)。
  3. 顯式初始化/構造器執行:按聲明順序執行賦值語句,然後執行構造器參數邏輯。
  4. 引用賦值:棧帧局部變量表存入指向堆對象的引用地址。

通俗版:堆中新建對象 → 構造方法初始化 → 棧中存引用。

實戰陷阱:父類字段初始化時機導致的「共享引用」Bug

問題代碼

public class Pet {
    protected Bean be = this.b();  // 父類實例化時執行

    public Bean b() { return new Bean(); }
}

public class People extends Pet {
    public void test() { be.setName("張三"); }
    public void test2() { System.out.println(be.getName()); }

    public static void main(String[] args) {
        People pe = new People();
        pe.test();
        pe.test2();  // 輸出 "張三" ✅
    }
}

修改後出現 Bug

public void test() {
    Bean be = new Bean();  // 方法局部變量,遮蔽父類字段!
    be.setName("張三");
}
public void test2() {
    System.out.println(be.getName());  // 訪問父類字段 be,仍為 null ❌
}

原因:test() 中 new Bean() 賦值給局部變量,父類字段 be 未被修改,test2() 讀取的是父類字段(null)。

解決方案:單例模式統一管理共享對象

懶漢式(線程安全雙重檢查鎖)

public class Singleton {
    // 1. 私有構造器
    private Singleton() {}

    // 2. volatile 防止指令重排序
    private static volatile Singleton instance;

    // 3. 公開靜態獲取方法
    public static Singleton getInstance() {
        if (instance == null) {                    // 第一次檢查
            synchronized (Singleton.class) {       // 加鎖
                if (instance == null) {            // 第二次檢查
                    instance = new Singleton();    // 實例化
                }
            }
        }
        return instance;
    }
}

枚舉單例(最簡潔、防反射/序列化破壞)

public enum Singleton {
    INSTANCE;
    public void doSomething() { System.out.println("做點事"); }
}
// 使用:Singleton.INSTANCE.doSomething();

為什麼推薦單例管理共享對象?

痛點單例解決
多處 new 導致多實例、狀態不一致全局唯一實例,狀態集中管理
頻繁創建銷毀增加 GC 壓力常駐內存,復用無開銷
構造器邏輯複雜、耗時首次調用初始化,後續直接返回

記憶口訣

new 四步:分內存、默初始、顯初始、跑構造、存引用。
父類字段慎遮蔽,局部變量別同名。
共享對象用單例,枚舉最簡又安全。

總結

  1. new 是對象創建的核心操作,理解其內存分配與初始化順序是排查 OOM、初始化異常的基礎。
  2. 繼承體系中字段遮蔽是高發 Bug 區,父類共享對象應在構造器/初始化塊中統一創建。
  3. 單例模式(尤其是枚舉實現)是管理全局共享對象的標準解法,兼顧線程安全、防反射、防序列化破壞。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved