初学 Java 的人很不经意间就会把常量定义在接口中, 大概唯一的理由是接口不能实例化, 而使用接口中定义的常量也是不用附着在实例上的. 这主要还是 JDK 本身给我们做了很多这样的榜样, 如 java.io.ObjectStreamConstans http://docs.oracle.com/javase/7/docs/api/java/io/ObjectStreamConstants.html , 多是出现在 Enum 类型到来之前.
其实 Java 的接口常量是一种反模式, 理由如下:
1. 接口是不能阻止被实现或继承的, 也就是说子接口或实现中是能够覆盖掉常量的定义, 这样通过父, 子接口 (或实现) 去引用常量是可能不一致的
2. 同样的, 由于被实现或继承, 造成在继承树中可以用大量的接口, 类 或实例去引用 同一个常量, 从而造成接口中定义的常量污染了命名空间.(Java 编译器竟然允许使用实例去引用类变量)
3. 接口暗含的意思是: 它是需被实现的, 代表着一种类型, 它的公有成员是要被暴露的 API. 而在接口中定义的常量说不上是 API
参见: Effective java 第 19 条: 接口只用于定义类型 http://blog.csdn.net/hosterzhu/article/details/9833665
既然接口中不适于定义常量, 那么该在何处为常量安家呢? 接口为 实现 / 继承 而生, 如果放在类中, 并且这个类是 final, 且封闭掉构造方法就行. 于是我们先前的接口常量定义
来源: http://www.bubuko.com/infodetail-2627478.html