假设您需要定义一个仅包含常量的类。
public static final String SOME_CONST = "SOME_VALUE";
这样做的首选方式是什么?
- 接口
- 抽象类
- 最终班
我应该使用哪一个?为什么?
澄清一些答案:
枚举-我将不使用枚举,我不会枚举任何东西,只是收集一些彼此不相关的常量。
接口-我不会将任何类设置为实现该接口的类。只是想使用该接口来调用常量,如下所示:ISomeInterface.SOME_CONST
。
假设您需要定义一个仅包含常量的类。
public static final String SOME_CONST = "SOME_VALUE";
这样做的首选方式是什么?
我应该使用哪一个?为什么?
枚举-我将不使用枚举,我不会枚举任何东西,只是收集一些彼此不相关的常量。
接口-我不会将任何类设置为实现该接口的类。只是想使用该接口来调用常量,如下所示:ISomeInterface.SOME_CONST
。
Answers:
使用期末课程。为简单起见,您可以使用静态导入在另一个类中重用您的值
public final class MyValues {
public static final String VALUE1 = "foo";
public static final String VALUE2 = "bar";
}
在另一堂课中:
import static MyValues.*
//...
if(variable.equals(VALUE1)){
//...
}
VALUE1.equals(variable)
避免使用NPE。
您的澄清指出:“我不会使用枚举,我不会枚举任何东西,只是收集一些彼此不相关的常量。”
如果这些常量根本不相关,那么为什么要一起收集它们呢?将每个常量都放在与其最相关的类中。
我的建议(按优先级从高到低的顺序):
1)不要这样做。在最相关的实际类中创建常量。拥有“常量包”类/接口并不是真正遵循OO最佳实践。
我和其他所有人不时忽略#1。如果您要这样做,那么:
2)使用私有构造函数的最终类这至少可以防止任何人通过扩展/实现它来轻松访问常量来滥用您的“常量包”。(我知道你说过你不会这样做-但这并不意味着有人会在你不愿意之后出现)
3)界面这将起作用,但我不愿意在#2中提及可能的滥用。
通常,仅仅因为这些是常量并不意味着您仍然不应该对它们应用常规的oo原理。如果只有一个类关心某个常量,则该常量应该是私有的,并且在该类中。如果仅测试关心常量,则应在测试类中,而不是生产代码中。如果在多个位置定义了一个常量(不只是偶然),请重构以消除重复。依此类推-像对待方法一样对待它们。
正如Joshua Bloch在Effective Java中所述:
如果所有常量都相关(例如行星名称),则可以使用Enum;将常量值放入与其相关的类中(如果可以访问它们);或者可以使用不可实例化的实用程序类(定义私有默认构造函数) 。
class SomeConstants
{
// Prevents instanciation of myself and my subclasses
private SomeConstants() {}
public final static String TOTO = "toto";
public final static Integer TEN = 10;
//...
}
然后,如前所述,您可以使用静态导入来使用常量。
enum
s很好。IIRC,有效的Java(第二版)中的enum
一项具有常量,该常量枚举interface
为任何值实现[Java关键字]的标准选项。
我的选择是使用[关键字的Java]interface
在一个final class
常量。您隐式获得public static final
。有人会争辩说,aninterface
允许不良的程序员来实现它,但是不良的程序员将编写代码,无论您做什么都糟透了。
哪个看起来更好?
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.";
}
或者4.将它们放在包含最常使用常量的逻辑的类中
...对不起,无法抗拒;-)
私有构造函数的缺点之一是方法的存在是无法测试的。
通过本质概念枚举可以很好地应用于特定的域类型,将其应用于分散的常量看起来不够好
枚举的概念是“枚举是一组紧密相关的项目”。
扩展/实现常量接口是一种不好的做法,很难考虑需要扩展不可变常量而不是直接引用它。
如果应用诸如SonarSource之类的质量工具,则有规则迫使开发人员放弃常量接口,这很尴尬,因为许多项目都喜欢常量接口,而很少看到“扩展”在常量接口上发生的事情