假设您需要定义一个类,它所做的就是保持常量.
public static final String SOME_CONST = "SOME_VALUE";
这样做的首选方式是什么?
接口
抽象类
最后一堂课
我应该使用哪一个?为什么?
枚举 - 我不会使用枚举,我不会枚举任何东西,只是收集一些与任何方式无关的常量.
接口 - 我不打算将任何类设置为实现接口的类.只想使用接口调用常量,如下所示:ISomeInterface.SOME_CONST
.
使用最后一堂课.为简单起见,您可以使用静态导入在另一个类中重用您的值
public final class MyValues { public static final String VALUE1 = "foo"; public static final String VALUE2 = "bar"; }
在另一个班级:
import static MyValues.* //... if(variable.equals(VALUE1)){ //... }
你的澄清说明:"我不会使用枚举,我不会枚举任何东西,只是收集一些与任何方式无关的常量."
如果常量根本不相关,为什么要将它们一起收集?将每个常量放在与其最密切相关的类中.
我的建议(按优先顺序递减):
1)不要这样做.在实际类中创建最相关的常量.拥有一个"常量包"类/接口并不是真正遵循OO最佳实践.
我和其他所有人不时忽略#1.如果你打算这样做那么:
2)具有私有构造函数的final类这至少可以防止任何人通过扩展/实现它来轻松访问常量来滥用你的"常量包".(我知道你说你不会这样做 - 但这并不意味着有人跟你走后不会)
3)界面这将起作用,但不是我的偏好,在#2中提到可能的滥用.
一般来说,仅仅因为这些是常数并不意味着你不应该仍然对它们应用正常的oo原则.如果班上没有人关心常数 - 它应该是私人的,并且在那个班级.如果只有测试关心常量 - 它应该在测试类中,而不是生产代码.如果在多个位置定义常量(不仅意外地相同) - 重构以消除重复.等等 - 像对待方法一样对待它们.
正如Joshua Bloch在Effective Java中所说:
接口应仅用于定义类型,
抽象类不会阻止不稳定性(它们可以被子类化,甚至建议它们被设计为子类).
如果所有常量都相关(如行星名称),则可以使用枚举,将常量值放在与它们相关的类中(如果您有权访问它们),或使用非实例化实用程序类(定义私有默认构造函数) .
class SomeConstants { // Prevents instanciation of myself and my subclasses private SomeConstants() {} public final static String TOTO = "toto"; public final static Integer TEN = 10; //... }
然后,如前所述,您可以使用静态导入来使用常量.
我首选的方法是根本不这样做.当Java 5引入类型安全枚举时,常量的年龄几乎消失了.甚至在此之前,Josh Bloch发布了一个(稍微冗长的罗嗦)版本,它适用于Java 1.4(及更早版本).
除非您需要与某些遗留代码的互操作性,否则实际上没有理由再使用命名的字符串/整数常量.