Effective Java 2.0_中英文對照_Item 4

文章作者:Tyan
博客:noahsnail.com ?|? CSDN ?|? 簡書

Item 4: Enforce noninstantiability with a private constructor

Occasionally you’ll want to write a class that is just a grouping of static methods and static fields. Such classes have acquired a bad reputation because some people abuse them to avoid thinking in terms of objects, but they do have valid uses. They can be used to group related methods on primitive values or arrays, in the manner of java.lang.Math or java.util.Arrays. They can also be used to group static methods, including factory methods (Item 1), for objects that implement a particular interface, in the manner of java.util.Collections. Lastly, they can be used to group methods on a final class, instead of extending the class.

有時你會想寫一個只包含一組靜態(tài)方法和靜態(tài)變量的類。這種類的名聲很不好,因為有些人濫用它們來避免思考如何面向?qū)ο螅鼈兇_實是有用的。它們可以用來以java.lang.Mathjava.util.Arrays的方式來組織與基本類型或數(shù)組相關(guān)的方法。它們也可以用來以java.util.Collections的方式來組織實現(xiàn)特定接口對象的靜態(tài)方法,包括工廠方法(Item 1)。最后,它們可以用來組織一個fianl類的方法,從而代替擴展這個類。

Such utility classes were not designed to be instantiated: an instance would be nonsensical. In the absence of explicit constructors, however, the compiler provides a public, parameterless default constructor. To a user, this constructor is indistinguishable from any other. It is not uncommon to see unintentionally instantiable classes in published APIs.

這種工具類被設(shè)計成不能實例化:它的實例是沒有意義的。然而,在缺少顯式構(gòu)造函數(shù)的情況下,編譯器會提供一個公有的無參構(gòu)造默認(rèn)函數(shù)。對用戶而言,這個構(gòu)造函數(shù)與其它的構(gòu)造函數(shù)沒有任何差別。在發(fā)布的APIs中看到無意義的可實例化類是很罕見的。

**Attempting to enforce noninstantiability by making a class abstract does not work. **The class can be subclassed and the subclass instantiated.
Furthermore, it misleads the user into thinking the class was designed for inheritance (Item 17). There is, however, a simple idiom to ensure noninstantiability. A default constructor is generated only if a class contains no explicit constructors, so a class can be made noninstantiable by including a private constructor:

企圖通過聲明一個類為抽象類來強制類不能被實例化是行不通的。這個類可以被子類化,子類可以被實例化。而且,它會使用戶誤認(rèn)為這個類是為繼承而設(shè)計的(Item 17)。然而有一些簡單的習(xí)慣用法可以確保類不能被實例化。如果一個類沒有顯式的構(gòu)造函數(shù),會產(chǎn)生默認(rèn)的構(gòu)造函數(shù),因此,一個含有私有構(gòu)造函數(shù)的類不能被實例化:

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

Because the explicit constructor is private, it is inaccessible outside of the class. The AssertionError isn’t strictly required, but it provides insurance in case the constructor is accidentally invoked from within the class. It guarantees that the class will never be instantiated under any circumstances. This idiom is mildly counterintuitive, as the constructor is provided expressly so that it cannot be invoked. It is therefore wise to include a comment, as shown above.

因為顯式構(gòu)造函數(shù)是私有的,因此類的外部不能訪問構(gòu)造函數(shù)。AssertionError不是必須的,但它可以避免類內(nèi)部無意的調(diào)用構(gòu)造函數(shù)。這種習(xí)慣用法有點違背直覺,似乎構(gòu)造函數(shù)的提供就是為了它不能被調(diào)用一樣。因此明智的做法是在類中加上注釋,像上面的例子一樣。

As a side effect, this idiom also prevents the class from being subclassed. All constructors must invoke a superclass constructor, explicitly or implicitly, and a subclass would have no accessible superclass constructor to invoke.

這種習(xí)慣用法的一個副作用就是阻止了類的子類化。子類的所有的構(gòu)造函數(shù)必須調(diào)用父類的構(gòu)造函數(shù),無論是顯式的或隱式的,但這種情況下子類不能調(diào)用父類構(gòu)造函數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容