《Effective Java 中文版 第二版》第二章 第4條:通過私有構造器強化不可實例化的能力

本章的主題是創建和銷毀對象:何時以及如何創建對象,何時以及如何避免創建對象,如何確保它們能夠適時地銷毀,以及如何管理對象銷毀之前必須進行的各種清理動作。


[toc]

有時候,你可能需要編寫只包含靜態方法和靜態域的類。雖然這些類名聲很不好,因為有些人在面向對象的語言中濫用這樣的類來編寫過程化的程序。盡管如此,它們也確實有它們特有的用處。我們可以利用這種類,以 java.lang.Math 或者 java.util.Arrays 的方式,把基本類型的值或者數組類型上的相關方法組織起來。我們也可以通過 java.util.Collections 的方式,把實現特定接口的對象上的靜態方法(包括靜態方法,見第1條)組織起來。最后還可以利用這種類把 final 類上的方法組織起來,以取代擴展該類的做法。

這樣的工具類(utility class)不希望被實例化,實例對它沒有任何意義。然而在缺少顯石子構造器的情況下,編譯器會自動提供一個公有的、無參的缺省構造器(default constructor)。對于用戶而言,這個構造器與其他構造器沒有任何區別。在已經發行的API中常??梢钥吹揭恍┍粺o意識地實例化的類。

企圖通過將類做成抽象類來強制該類不可被實例化,這是行不通的
該類可以被子類化,并且該子類也可以被實例化。這樣可能會誤導用戶,以為這種類是專門為了繼承而設計的(見 17 條)。

而我們只需要讓這個類只包含私有構造器,它就不能被實例化了:

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

由于顯式的構造器是私有的,所以不可以在該類的外部訪問它。AssertionError 不是必須的,它可以避免不小心在類的內部調用構造器,防止該類被實例化,這種習慣用法有點違背直覺,好像構造器就是專門設計成不能被調用一樣。所以最好加上一條注釋。如上所示。

副作用:

  • 使得一個類不能被子類化。
    所有的構造器都必須顯式或隱式地調用超類(superclass)構造器,在這種情況下,子類就沒有可訪問的超類構造器可調用了。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,740評論 18 399
  • 一:java概述:1,JDK:Java Development Kit,java的開發和運行環境,java的開發工...
    ZaneInTheSun閱讀 2,686評論 0 11
  • 本章將會介紹 存儲屬性的初始賦值自定義構造過程默認構造器值類型的構造器代理類的繼承和構造過程可失敗構造器必要構造器...
    寒橋閱讀 778評論 0 0
  • 因為骨子里很現實,擔憂自己變得現實,所以才會追求理想吧 被人說是理想主義者,好像也沒有什么不好的,現實真是讓人哭笑...
    ALeesa閱讀 206評論 0 0
  • 請認真思考一下,你的公司是不是存在著這樣的普遍現象—— 有5%~10%的公司員工,一上班就是來挑毛病、和你對著干,...
    小聲講故事閱讀 281評論 0 0