在整个申请过程中,您在哪里使用Constants?

界面是一个可以接受的地方来存储我的

public static final Foo bar 

你是否推断它们是从程序外读取的? 你为它组成一个超级class吗?

当情况出现时,你是如何做到的?

我将每个常量放入与它最密切相关的类或接口中(例如,因为它将通过其方法使用)。

一个非常诱人但最终非常愚蠢的想法是拥有一个包含应用程序中使用的所有常量的“常量类”(或接口)。 这看起来很“整洁”,但是对于可维护性并不好,因为你想通过它们实现的function来分组,而不是像常量这样的技术细节(你会把所有接口都放到一个专用的包中吗?所有的抽象类?) 。

这个想法也是愚蠢的,因为对那个类/接口的任何改变(因为常量内联)需要重建所有使用任何常量的类 – 即几乎整个应用程序。 因此,应用程序越大,您需要进行此类完全重建的频率越高,所需的时间就越长。 我参与了这样一个项目,这个问题导致每个开发人员每隔一天停顿15分钟……

如果你在谈论一个简单的应用程序,那么Constants类的方法很好:

 public class Constants { private Constants() {} // no way to instantiate this class public static final String MY_VAL = "123"; } 

如果您正在构建一个更大的应用程序,您应该使用dependency injection,请查看如何将属性值注入使用注释配置的Spring Bean?

我使用了Abdullah Jibaly的方法但使用了嵌套类,这为分组consts提供了一种很好的方法。 我已经看到这个深入3级,如果选择好名字,它仍然可以很好地工作。

有人可能会选择使用final类来代替接口类,以避免违反Josh Bloch列表中的第19项(Effective Java 2nd edition)。

 public final class Const { private Const() {} // prevent instantiation /** Group1 constants pertain to blah blah blah... */ public static final class Group1 { private Group1() {} // prevent instantiation public static final int MY_VAL_1 = 1; public static final int MY_VAL_2 = 42; } /** Group2 constants pertain to blah blah blah... */ public static final class Group2 { private Group2() {} // prevent instantiation public static final String MY_ALPHA_VAL = "A"; public static final String MY_ALPHA_VAL = "B"; } } 

这是不好的做法。 类应该彼此独立,因此您应该不惜一切代价避免使用全局变量。 更现实的方法是使用配置文件,通常采用JSONYAMLXML文件格式,并在启动时从该文件中读取程序。

我会使用一个abstract final class因为它将是一个更明确的修饰符声明,而不是使用接口。 但是,就像迈克尔所说,如果它们在语义上属于那里,它们应该在逻辑上分组并成为现有类或接口的一部分。