網頁

2020/6/20

Effective Java 3e - Item 4: Enforce noninstantiability with a private constructor 筆記

Effective Java 3e - Item 4: Enforce noninstantiability with a private constructor 使用private建構式使無法實例化。

Java偶爾會需要工具類別(utility class)用來組織多個靜態方法(static method)。而靜態方法的使用並不需要透過實例,因此工具類不需實例化。

Java對無建構式的類別預設會產生一個無參數建構式,且類別也可被繼承的子類別產生實例,因此像工具類等不需實例化的類別應使其無法實例化(noninstantiability)。

要讓類別無法被實例化可在類別中撰寫唯一的private建構式,並在建構式中拋出AssertionError()UnsupportedOperationException避免實例在類別內部產生。

例如下面的DemoUtility即不可實例化。建構式是private的。

public class DemoUtility {

    private DemoUtility() {
        throw new AssertionError("DemoUtility is noninstantiable");
    }
    
}

類別只有private建構式則無法繼承,因為子類別建構式中必須透過super()呼叫父類別的建構式,但父類別只有唯一的private建構式,導致子類別無法呼叫因此無法繼承。


經網友提醒,或可使用lombok的@UtilityClass讓類別成為工具類別,使具有隱蔽建構式,無法繼承及覆寫及提供靜態方法的效果。


2 則留言:

  1. 我剛好好奇, 所以比對了一下 Lombok 的 UtitlyClass 設計, 就在這邊補充一下
    在 LOMBOK 的 @UtitlyClass 設計上, UtitlyClass 是 final 的宣告, 且拋出的 Exception 為 java.lang.UnsupportedOperationException

    https://projectlombok.org/features/experimental/UtilityClass

    回覆刪除
  2. @冬天好涼,感謝您的補充資訊讓我知道lombok的@UtilityClass。看了一下我想核心概念是一樣的,就是隱蔽建構式且無法繼承。而我這邊的範例作者是用AssertionError,我也覺得lombok用UnsupportedOperetionException也不錯。

    回覆刪除