Tips
《Effective Java, Third Edition》一書英文版已經出版,這本書的第二版想必不少人都讀過,號稱Java四大名著之一,不過第二版2009年出版,到如今已經將近8年的時間,但隨着Java 6,7,8,甚至9的發佈,Java語言發生了深入的變化。
在這裏第一時間翻譯成中文版。供你們學習分享之用。java
當類實現接口時,該接口做爲一種類型(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
若是你想導出常量,有幾個合理的選擇方案。 若是常量與現有的類或接口緊密相關,則應將其添加到該類或接口中。 例如,全部數字基本類型的包裝類,如Integer
和Double
,都會導出MIN_VALUE
和MAX_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 }
總之,接口只能用於定義類型。 它們不該該僅用於導出常量。接口