以 new MyDate(22, 7, 1964) 為例:
MyDate 實例數據。0/null/false)。通俗版:堆中新建對象 → 構造方法初始化 → 棧中存引用。
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(); // 輸出 "張三" ✅
}
}
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 四步:分內存、默初始、顯初始、跑構造、存引用。 父類字段慎遮蔽,局部變量別同名。 共享對象用單例,枚舉最簡又安全。
new 是對象創建的核心操作,理解其內存分配與初始化順序是排查 OOM、初始化異常的基礎。