最近在看一本书 Java与模式,里面提了一句不建议使用常量接口,甚至举了个java源码的反例,java
蛋疼的是没有说为何?网络
查了网上一圈发现他们也是知道怎么作而不知道为何这么作。数据结构
而后我只能找谷歌了,翻译后,我把本身理解外加总结的放在下面。架构
常量类应该是final,不变的,而接口里的参数是final,也是不变的。this
那么,看起来接口是放常量没有必定问题,还省去了final的输入,很是的合适。网络传输协议
可是,类是只能单继承的,接口是容许多实现的。spa
要是类实现的多个接口出现重名的常量,会报错,必需要在实现类明确常量用的是哪一个接口的。翻译
虽然这能够说是架构师设计的问题,可是,架构师这么作就违反了依赖倒转原则,这玩意就不细说了。设计
若是某个实现了常量接口的类被修改再也不须要常量了,也会由于序列化兼容缘由不得不保持该实现,并且非final类实现常量接口会致使全部子类被污染。code
这个应该不多人遇到过,不过这是 Effective Java 里面说的。
具体的理解就是,能被序列化的必定是数据,
那么忽然改了数据结构,可能致使老版的数据没法被反序列化,而新版的数据会有冗杂的数据,
要是折腾个几回,网络传输协议 这个没法经过时间或者空间提高的玩意就能逼死你了。
Effective Java 做者 大佬的原话
According to Joshua Bloch, author of "Effective Java":
The constant interface pattern is a poor use of interfaces.
That a class uses some constants internally is an implementation detail.
Implementing a constant interface causes this implementation detail to leak into the class's exported API.
It is of no consequence to the users of a class that the class implements a constant interface.
In fact, it may even confuse them. Worse, it represents a commitment:
if in a future release the class is modified so that it no longer needs to use the constants,
it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface,
all of its subclasses will have their namespaces polluted by the constants in the interface.
基于数据只暴露给相应的类的原则,一个类实现一个常量接口,可能只须要其中几个常量,而获得了更多无用的常量,
因此,使用常量接口的时候都是
import static const.valueAAA
那此时和常量类有区别吗?
接口是定义类型的,而不该该用于导出常量。常量接口不建议使用,应使用常量类。