初學者常困惑:為什麼有時看到 `User user = userService.getUser()` 直接得到對象,沒寫 `new User()`?實則對象依然被創建了,只是創建責任轉移給了其他組件。
// 客戶端代碼
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 在這裡
}
}
優勢:封裝複雜構建邏輯、支持單例/原型模式、解耦具體實現類。
@Service
public class UserService {
@Autowired private UserRepository repo; // 容器 new 並注入
public User getUser(Long id) {
return repo.findById(id).orElse(null); // 返回已管裝的實體
}
}
Spring 容器啟動時掃描 `@Component` 等註解,預先實例化 Bean 並存入 IOC 容器,運行期直接從容器獲取,提升首次響應速度。
Class> clazz = Class.forName("com.demo.User");
User user = (User) clazz.getDeclaredConstructor().newInstance(); // 運行時 new
框架(如 ORM、序列化庫)大量使用反射根據類名動態創建對象。
User prototype = new User("template");
User clone = (User) prototype.clone(); // 不調用構造器,內存拷貝
| 方式 | 創建者 | 生命週期管理者 | 典型場景 |
|---|---|---|---|
| 直接 new | 調用者 | 調用者 | 簡單臨時對象 |
| 工廠 | 工廠類 | 調用者 | 邏輯複雜、需解耦 |
| DI 容器 | 容器 | 容器 | Service、Repository、Controller |
| 反射 | 框架代碼 | 框架/調用者 | ORM、反序列化、插件系統 |
Java 中「不寫 new 也能得到對象」本質是創建職責分離:工廠封裝邏輯、容器管理生命週期、框架反射動態創建。掌握這背後的設計模式與容器機制,才能寫出低耦合、高可測、易維護的企業級代碼。