Effective Java(3rd)-Item22 接口仅用来
当类实现了接口时,接口可用作引用类实例的类型。因此,类实现接口应该说明客户端可以对类的实例做什么。为任何其他目的定义接口是不合适的。
一种未通过此测试的接口是所谓的常量接口。如此接口不包含任何方法;它仅由静态final字段组成,每个字段都输出一个常量。使用这些常量的类实现接口,以避免使用类名限定常量名称。这是一个例子:
image.png
常量接口模式是接口的不良使用。类在内部使用一些常量是一种实现细节。实现一个常量接口会造成该实现细节泄漏到类的导出API中。类的用户实现一个常量接口并没有意义。事实上,它甚至可能会使它们感到困惑。更糟的是,它代表了一个承诺:如果在未来的版本中修改了类,以至于它不再需要使用常量,但它仍然必须实现接口来确保二进制的兼容性。如果一个非final类实现了一个常量接口,所有它的子类的命名空间都会受到接口常量的污染。
Java平台库有一些常量接口,比如
java.io.ObjectStreamConstants。这些接口应该视为异常,不应该被模仿。
如果你想要导出常量,有几个合理的选择。如果常量与已存在的类或接口有着紧密联系,你应该将它们添加到类或接口中。例如,所有装箱数字基本类(比如Integer和Double,导出MIN_VALUE和MAX_VALUE常量)。如果常量最好被使用枚举类型的成员,你应该导出它们未枚举类型(item34) 。否则,你应该使用不可实例化的工具类导出常量(item4) 。这是先前显示的PhysicalConstants实例的工具类版本:
顺便提一下,注意在数字文字中使用下划线字符(_)。自java7以来,下划线一直是合法的,对数字文字的值没有影响,但是如果谨慎使用,可以使它们更容易阅读。如果数字文字包含五个或更多连续数字,考虑将下划线添加到它们中,无论浮点数是否固定。对于基数为十的文字,无论是整数还是浮点,你都应该用下划线将文字分为三个数字的组,表述一千的正负幂。
通常,一个工具类需要客户端使用类名修饰常量名,比如PhysicalConstants.AVOGADROS_NUMBER。如果你大量使用工具类的常量,你可以通过使用静态导入工具避免类名限定常量:
image.png
总之,接口仅用于定义类型。它们不该被仅仅用来导出常量。
本文写于2019.4.16,历时1天