Tips
《Effective Java, Third Edition》一書英文版已經出版,這本書的第二版想必不少人都讀過,號稱Java四大名著之一,不過第二版2009年出版,到如今已經將近8年的時間,但隨着Java 6,7,8,甚至9的發佈,Java語言發生了深入的變化。
在這裏第一時間翻譯成中文版。供你們學習分享之用。java
偶爾你會想寫一個類,它只是一組靜態方法和靜態屬性。 這樣的類得到了很差的名聲,由於有些人濫用這些類而避免以面向對象方式思考,可是它們確實有着特殊的用途。 它們能夠用來按照java.lang.Math
或java.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
異常不是嚴格要求的,可是它提供了一種保證,以防在類中意外地調用構造方法。它保證類在任何狀況下都不會被實例化。這個習慣用法有點違反直覺,好像構造方法就是設計成不能調用的同樣。所以,如前面所示,添加註釋是種明智的作法。設計
這種習慣有一個反作用,阻止了類的子類化。全部的構造方法都必須顯式或隱式地調用父類構造方法,而子類則沒有可訪問的父類構造方法來調用。code