Effective Java 第三版——4. 使用私有構造方法執行非實例化


Tips
《Effective Java, Third Edition》一書英文版已經出版,這本書的第二版想必很多人都讀過,號稱Java四大名著之一,不過第二版2009年出版,到現在已經將近8年的時間,但隨着Java 6,7,8,甚至9的發布,Java語言發生了深刻的變化。
在這里第一時間翻譯成中文版。供大家學習分享之用。

Effective Java, Third Edition

4. 使用私有構造方法執行非實例化

偶爾你會想寫一個類,它只是一組靜態方法和靜態屬性。 這樣的類獲得了不好的名聲,因為有些人濫用這些類而避免以面向對象方式思考,但是它們確實有着特殊的用途。 它們可以用來按照java.lang.Mathjava.util.Arrays的方式,在基本類型的數值或數組上組織相關的方法。 它們也可以用於將靜態方法(包括工廠(條目 1))分組,用於實現某個接口的對象,其方式為java.util.Collections。 (從Java 8開始,你也可以將這些方法放在接口中,假如它是你自己修改的。)最后,這樣的類可以用於在final類上對方法進行分組,因為不能將它們放在子類中。

這樣的實用類( utility classes)不是設計用來被實例化的:一個實例是沒有意義的。然而,在沒有顯式構造方法的情況下,編譯器提供了一個公共的、無參的默認構造方法。對於用戶來說,該構造方法與其他構造方法沒有什么區別。在已發布的 API中經常看到無意識的被實例的類。

試圖通過創建抽象類來強制執行非實例化是行不通的。該類可以被子類化,子類可以被實例化。此外,它誤導用戶認為該類是為繼承而設計的(條目 19)。不過,有一個簡單的方法來確保非實例化。只有當類不包含顯式構造方法時,才會生成一個默認構造方法,因此可以通過包含一個私有構造方法來實現類的非實例化:

// Noninstantiable utility class
public class UtilityClass {
    // Suppress default constructor for noninstantiability
    private UtilityClass() {
        throw new AssertionError();
    }
    ... // Remainder omitted
}

因為顯式構造方法是私有的,所以在類之外是不可訪問的。AssertionError異常不是嚴格要求的,但是它提供了一種保證,以防在類中意外地調用構造方法。它保證類在任何情況下都不會被實例化。這個習慣用法有點違反直覺,好像構造方法就是設計成不能調用的一樣。因此,如前面所示,添加注釋是種明智的做法。

這種習慣有一個副作用,阻止了類的子類化。所有的構造方法都必須顯式或隱式地調用父類構造方法,而子類則沒有可訪問的父類構造方法來調用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM