假设您需要定义一个类,它所做的就是保持常量。
public static final String SOME_CONST = "SOME_VALUE";
这样做的首选方式是什么?
我应该使用哪一个?为什么?
<小时/> 澄清一些答案:
枚举 - 我不打算使用枚举,我不会枚举任何内容,只是收集一些彼此无关的常量。
接口 - 我不打算将任何类设置为实现接口的类。只想使用接口调用常量,如:ISomeInterface.SOME_CONST
。
答案 0 :(得分:71)
使用最后一堂课。 为简单起见,您可以使用静态导入在另一个类中重用您的值
public final class MyValues {
public static final String VALUE1 = "foo";
public static final String VALUE2 = "bar";
}
在另一个班级:
import static MyValues.*
//...
if(variable.equals(VALUE1)){
//...
}
答案 1 :(得分:36)
你的澄清说:“我不会使用枚举,我不会枚举任何东西,只是收集一些与任何方式无关的常量。”
如果常量根本不相关,为什么要将它们一起收集?将每个常量放在与它最密切相关的类中。
答案 2 :(得分:19)
我的建议(按优先顺序递减):
1)不要这样做。在实际类中创建最相关的常量。拥有一个“常量包”类/接口并不是真正遵循OO最佳实践。
我和其他所有人不时忽略#1。如果你打算这样做那么:
2)带有私有构造函数的最终类这至少可以防止任何人通过扩展/实现它来轻松访问常量来滥用你的“常量包”。 (我知道你说你不会这样做 - 但这并不意味着有人跟你走后不会这样做)
3)界面这样可行,但不是我的偏好,可能会在#2中提及可能的滥用行为。
一般来说,仅仅因为这些是常数并不意味着你不应该仍然对它们应用正常的oo原则。如果班上没有人关心常数 - 它应该是私人的,并且在那个班级。如果只有测试关心常量 - 它应该在测试类中,而不是生产代码。如果在多个位置定义常量(不仅意外地相同) - 重构以消除重复。等等 - 像对待方法一样对待它们。
答案 3 :(得分:12)
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;
//...
}
然后,如前所述,您可以使用静态导入来使用常量。
答案 4 :(得分:6)
我首选的方法是不要这样做。当Java 5引入类型安全枚举时,常量的年龄几乎消失了。甚至在此之前,Josh Bloch发布了一个(稍微冗长的罗嗦)版本,它适用于Java 1.4(及更早版本)。
除非您需要与某些遗留代码进行互操作,否则我们就没有理由再使用命名字符串/整数常量了。
答案 5 :(得分:3)
只需使用最终课程。
如果您希望能够添加其他值,请使用抽象类。
使用接口没有多大意义,接口应该指定合同。您只想声明一些常量值。
答案 6 :(得分:3)
这些东西不是enums最佳选择吗?
答案 7 :(得分:3)
enum
很好。 IIRC,有效Java(第二版)中的一个项目有enum
个常量,用于枚举为任何值实现[Java关键字] interface
的标准选项。
我的偏好是对interface
使用[Java关键字] final class
作为常量。你暗中得到了public static final
。有些人会争辩说interface
允许糟糕的程序员实现它,但是不管你做什么,糟糕的程序员都会编写糟透的代码。
哪个看起来更好?
public final class SomeStuff {
private SomeStuff() {
throw new Error();
}
public static final String SOME_CONST = "Some value or another, I don't know.";
}
或者:
public interface SomeStuff {
String SOME_CONST = "Some value or another, I don't know.";
}
答案 8 :(得分:1)
或4.将它们放在包含使用最常量
的逻辑的类中...对不起,无法抗拒; - )
答案 9 :(得分:0)
对我来说最好的方法是enum
:
public enum SomeApiConstants {;
public static final String SOME_CONST = "SOME_VALUE";
//may be in hierarchy
public enum ApiMapping {;
public static final String VERSION = "/version";
public static final String VERSION_LIST = "/list/{type}";
}
}
优点:
java: enum types may not be instantiated