私有建構子(private constructor)是 Java 類別設計中的重要模式,常用於單例、工具類、工廠模式等場景。本文透過一個 Hibernate SessionFactory 實例,剖析私有建構子的作用、導致實例化失敗的典型錯誤,以及正確的使用方式。
public class HibernateSessionFactory {
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal threadLocal = new ThreadLocal();
private static final Configuration cfg = new Configuration();
private static net.sf.hibernate.SessionFactory sessionFactory;
public static Session currentSession() throws HibernateException { ... }
public static void closeSession() throws HibernateException { ... }
// 私有建構子
private HibernateSessionFactory() { }
}
此類採用執行緒區域儲存模式,所有方法均為 static,不需實例即可操作。私有建構子明確禁止外部 new HibernateSessionFactory()。
public class HibernatePlugin implements PlugIn {
private HibernateSessionFactory hsf;
public HibernatePlugin() {
hsf = new HibernateSessionFactory(); // 編譯錯誤!
}
...
}
錯誤訊息:HibernateSessionFactory() has private access in zy.pro.td.util.HibernateSessionFactory
開發者為了通過編譯,將建構子改為 public,卻違背了原設計意圖。
java.lang.Math, Collections)。getInstance() 控制唯一實例建立。Boolean.valueOf())。呼叫端應直接使用靜態方法,而非嘗試實例化:
public class HibernatePlugin implements PlugIn {
public void init(ActionServlet servlet, ModuleConfig config) {
// 正確:直接呼叫靜態方法
Session session = HibernateSessionFactory.currentSession();
// 後續操作...
}
// 移除 hsf 欄位與建構子中的 new HibernateSessionFactory()
}
| 誤區 | 正確做法 |
|---|---|
| 為了方便實例化,將私有建構子改為 public | 理解類別設計意圖,改用靜態介面或依賴注入取得實例 |
| 以為私有建構子代表類別完全不可用 | 私有僅阻擋 new,靜態成員仍可正常存取 |
| 子類別嘗試繼承含私有建構子的類別 | 私有建構子隱含 final 語意,無法被繼承(除非巢狀類別) |
私有建構子非障礙,而是設計契約的一部分。遇到編譯錯誤時,請先理解類別作者意圖:是否應改用靜態介面?是否遺漏了工廠方法?盲目改為 public 往往引入更深層的設計缺陷。掌握此模式,能寫出更清晰、安全的 API。