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

Java 對象創建不只靠 new:工廠模式、依賴注入與反射的深度解析

     編輯:程式設計綜合問答

現象觀察

初學者常困惑:為什麼有時看到 `User user = userService.getUser()` 直接得到對象,沒寫 `new User()`?實則對象依然被創建了,只是創建責任轉移給了其他組件。

四大「隱式 new」場景

1. 工廠模式 / 構建器模式

// 客戶端代碼
User user = UserFactory.create("admin", "123456"); // 內部 new User()

// 工廠內部
public class UserFactory {
    public static User create(String name, String pwd) {
        return new User(name, pwd); // 真正的 new 在這裡
    }
}

優勢:封裝複雜構建邏輯、支持單例/原型模式、解耦具體實現類。

2. 依賴注入 (Spring / CDI)

@Service
public class UserService {
    @Autowired private UserRepository repo; // 容器 new 並注入
    
    public User getUser(Long id) {
        return repo.findById(id).orElse(null); // 返回已管裝的實體
    }
}

Spring 容器啟動時掃描 `@Component` 等註解,預先實例化 Bean 並存入 IOC 容器,運行期直接從容器獲取,提升首次響應速度。

3. 反射動態實例化

Class clazz = Class.forName("com.demo.User");
User user = (User) clazz.getDeclaredConstructor().newInstance(); // 運行時 new

框架(如 ORM、序列化庫)大量使用反射根據類名動態創建對象。

4. 原型模式 / 拷貝構造

User prototype = new User("template");
User clone = (User) prototype.clone(); // 不調用構造器,內存拷貝

本質:new 發生在哪裡不重要,重要的是「誰負責生命週期」

方式創建者生命週期管理者典型場景
直接 new調用者調用者簡單臨時對象
工廠工廠類調用者邏輯複雜、需解耦
DI 容器容器容器Service、Repository、Controller
反射框架代碼框架/調用者ORM、反序列化、插件系統

常見誤區

  • ❌ 「沒寫 new 就不佔內存」—— 錯,對象終究在堆上分配
  • ❌ 「get 方法不 new 就能拿對象」—— 錯,內部必有 new 或從池/緩存取
  • ✅ 「Spring 的 getBean() 返回單例」—— 對,默認單例模式,全程僅 new 一次

最佳實踐建議

  1. 業務代碼盡量構造器注入依賴,而非自行 `new Service()`
  2. 複雜對象構建用Builder 模式,避免參數爆炸
  3. 大量臨時對象考慮對象池(如線程池、連接池)減少 GC 壓力
  4. 理解框架底層原理,遇到「對象從哪來」能快速定位源碼

總結

Java 中「不寫 new 也能得到對象」本質是創建職責分離:工廠封裝邏輯、容器管理生命週期、框架反射動態創建。掌握這背後的設計模式與容器機制,才能寫出低耦合、高可測、易維護的企業級代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved