如何在Java中定义一类常量?
假设您需要定义一个类,它所做的只是保存常量如何在Java中定义一类常量?,java,class-constants,Java,Class Constants,假设您需要定义一个类,它所做的只是保存常量 public static final String SOME_CONST = "SOME_VALUE"; 这样做的首选方式是什么 接口 抽象类 期末班 我应该使用哪一个?为什么 对一些答案的澄清: 枚举-我不会使用枚举,我不会枚举任何东西,只是收集一些彼此之间没有任何关联的常量 接口-我不会将任何类设置为实现接口的类。只想使用接口调用常量,如:isomointerface。一些常量只使用final类 如果希望能够添加其他值,请使用抽象类 使用接口
public static final String SOME_CONST = "SOME_VALUE";
这样做的首选方式是什么
对一些答案的澄清: 枚举-我不会使用枚举,我不会枚举任何东西,只是收集一些彼此之间没有任何关联的常量 接口-我不会将任何类设置为实现接口的类。只想使用接口调用常量,如:
isomointerface。一些常量只使用final类
如果希望能够添加其他值,请使用抽象类
使用接口没有多大意义,接口应该指定一个契约。您只需要声明一些常量值。不是这些类型的最佳选择吗?使用final类。
为了简单起见,您可以使用静态导入在另一个类中重用您的值
public final class MyValues {
public static final String VALUE1 = "foo";
public static final String VALUE2 = "bar";
}
在另一类中:
import static MyValues.*
//...
if(variable.equals(VALUE1)){
//...
}
我的首选方法是根本不这样做。当Java5引入类型安全枚举时,常量的时代几乎消失了。甚至在那之前,Josh Bloch发布了一个(稍微罗嗦一点的)版本,它适用于Java1.4(以及更早的版本)
除非您需要与某些遗留代码的互操作性,否则实在没有理由再使用命名字符串/整数常量。或4。将它们放入包含使用常量最多的逻辑的类中
。。。对不起,无法抗拒;-) 你的解释是:“我不会使用枚举,我不会枚举任何东西,只是收集一些彼此之间没有任何关联的常量。”
如果常数之间根本不相关,为什么要将它们收集在一起?将每个常量放在它最密切相关的类中。正如Joshua Bloch在《有效Java》中所指出的:
- 接口只能用于定义类型
- 抽象类不阻止实例化(它们可以被子类化,甚至暗示它们被设计成子类)
如果所有常量都相关(如行星名称),则可以使用枚举,将常量值放入与其相关的类中(如果您有权访问它们),或者使用不可实例化的实用程序类(定义专用默认构造函数)
然后,如前所述,您可以使用静态导入来使用常量。enum
s就可以了。IIRC,有效Java(第二版)中的一项具有枚举
常量,枚举实现[Java关键字]接口
的任何值的标准选项
public static final String SOME_CONST = "SOME_VALUE";
我更喜欢使用[Java关键字]接口,而不是最终类
作为常量。您隐式地获得了公共静态final
。有些人会争辩说,接口
允许差劲的程序员实现它,但差劲的程序员无论做什么都会写出糟糕的代码
哪个看起来更好
public final class SomeStuff {
private SomeStuff() {
throw new Error();
}
public static final String SOME_CONST = "Some value or another, I don't know.";
}
或:
我的建议(按优先顺序递减):
1) 不要这样做。在实际类中创建最相关的常量。拥有一个“常量包”类/接口并不是真正遵循OO最佳实践
一、 而其他人,时不时地忽略#1。如果你打算这样做,那么:
2) 带有私有构造函数的最终类这将至少防止任何人滥用您的“常量包”,方法是扩展/实现它以方便访问常量。(我知道你说过你不会这样做,但这并不意味着有人会在你之后不这样做)
3) 接口这会起作用,但我不喜欢在第2章中提到可能的滥用
一般来说,仅仅因为这些是常量并不意味着您不应该仍然对它们应用正常的oo原则。如果只有一个类关心常量,那么它应该是私有的,并且在该类中。如果只有测试关心常量,那么它应该在测试类中,而不是在生产代码中。如果在多个位置定义了常数(不仅仅是意外地定义了同一个),则重构以消除重复。以此类推——像对待方法一样对待他们
私有构造函数的缺点之一是方法的存在永远无法测试
枚举的本质概念很好地应用于特定的域类型,将其应用于分散的常量看起来还不够好
枚举的概念是“枚举是一组密切相关的项”
扩展/实现一个常量接口是一种糟糕的做法,很难考虑扩展一个不变常量而不是直接引用它的需求
如果应用SonarSource这样的质量工具,有规则迫使开发人员放弃常量接口,这是一件很尴尬的事情,因为很多项目都喜欢常量接口,很少看到在常量接口上发生“扩展”的事情
这里有一些类似的讨论:。我会使用带有私有构造函数的最后一个类,这样它就不能被实例化。抱歉,但是“我不打算使用枚举”将这个问题变成了“做蠢事的最佳方式是什么?”我并不是说你要实现接口。但使用接口来实现这一点毫无意义。最后一个类:)Enum有什么问题?您可以一直使用它来收集“一些彼此不相关的常数”。嗯?从概念上讲,如果常量不相关,枚举是一个错误的选择。枚举表示相同类型的可选值。这些常量不是可选的,它们甚至可能不是相同的类型(有些可能是字符串,有些是整数等)。这不是一个好主意。这会在类之间创建依赖关系
public interface SomeStuff {
String SOME_CONST = "Some value or another, I don't know.";
}