Effective Java 第三版——22. 接口僅用來定義類型

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

Effective Java, Third Edition

22. 接口僅用來定義類型

當類實現接口時,該接口做爲一種類型(type),能夠用來引用類的實例。所以,一個類實現了一個接口,所以代表客戶端能夠如何處理類的實例。爲其餘目的定義接口是不合適的。electron

一種失敗的接口就是所謂的常量接口(constant interface)。 這樣的接口不包含任何方法; 它只包含靜態final屬性,每一個輸出一個常量。 使用這些常量的類實現接口,以免須要用類名限定常量名。 這裏是一個例子:工具

// Constant interface antipattern - do not use!
public interface PhysicalConstants {
    // Avogadro's number (1/mol)
    static final double AVOGADROS_NUMBER   = 6.022_140_857e23;

    // Boltzmann constant (J/K)
    static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;

    // Mass of the electron (kg)
    static final double ELECTRON_MASS      = 9.109_383_56e-31;
}

常量接口模式是對接口的糟糕使用。類在內部使用一些常量,徹底屬於實現細節。實現一個常量接口會致使這個實現細節泄漏到類的導出API中。對類的用戶來講,類實現一個常量接口是沒有意義的。事實上,它甚至可能使他們感到困惑。更糟糕的是,它表明了一個承諾:若是在未來的版本中修改了類,再也不須要使用常量,那麼它仍然必須實現接口,以確保二進制兼容性。若是一個非final類實現了常量接口,那麼它的全部子類的命名空間都會被接口中的常量所污染。學習

Java平臺類庫中有多個常量接口,如java.io.ObjectStreamConstants。 這些接口應該被視爲不規範的,不該該被效仿。atom

若是你想導出常量,有幾個合理的選擇方案。 若是常量與現有的類或接口緊密相關,則應將其添加到該類或接口中。 例如,全部數字基本類型的包裝類,如IntegerDouble,都會導出MIN_VALUEMAX_VALUE常量。 若是常量最好被看做枚舉類型的成員,則應該使用枚舉類型(條目 34)導出它們。 不然,你應該用一個不可實例化的工具類來導出常量(條目 4)。 下是前面所示的PhysicalConstants示例的工具類的版本:翻譯

// Constant utility class
package com.effectivejava.science;

public class PhysicalConstants {
  private PhysicalConstants() { }  // Prevents instantiation

  public static final double AVOGADROS_NUMBER = 6.022_140_857e23;
  public static final double BOLTZMANN_CONST  = 1.380_648_52e-23;
  public static final double ELECTRON_MASS    = 9.109_383_56e-31;
}

順便提一下,請注意在數字文字中使用下劃線字符(_)。 從Java 7開始,合法的下劃線對數字字面量的值沒有影響,可是若是使用得當的話可使它們更容易閱讀。 不管是固定的浮點數,若是他們包含五個或更多的連續數字,考慮將下劃線添加到數字字面量中。 對於底數爲10的數字,不管是整型仍是浮點型的,都應該用下劃線將數字分紅三個數字組,表示一千的正負冪。code

一般,實用工具類要求客戶端使用類名來限定常量名,例如PhysicalConstants.AVOGADROS_NUMBER若是大量使用實用工具類導出的常量,則經過使用靜態導入來限定具備類名的常量blog

// Use of static import to avoid qualifying constants
import static com.effectivejava.science.PhysicalConstants.*;

public class Test {
    double  atoms(double mols) {
        return AVOGADROS_NUMBER * mols;
    }
    ...
    // Many more uses of PhysicalConstants justify static import
}

總之,接口只能用於定義類型。 它們不該該僅用於導出常量。接口

相關文章
相關標籤/搜索