我见过这样的例子:
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
假设我可以有一个Constants类来包装常量,并将它们声明为静态final。我几乎不知道Java,我想知道这是否是创建常量的最佳方式。
我见过这样的例子:
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
假设我可以有一个Constants类来包装常量,并将它们声明为静态final。我几乎不知道Java,我想知道这是否是创建常量的最佳方式。
当前回答
只是要避免使用接口:
public interface MyConstants {
String CONSTANT_ONE = "foo";
}
public class NeddsConstant implements MyConstants {
}
这很诱人,但违反了封装,并且模糊了类定义的区别。
其他回答
在Effective Java(第二版)中,建议对常量使用枚举而不是静态整型。
这里有一篇很好的关于Java中枚举的文章: http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
请注意,在那篇文章的最后提出的问题是:
那么什么时候应该使用枚举呢?
答案为:
任何时候你需要一个固定的常数集
一个好的面向对象设计不应该需要很多公开可用的常量。大多数常量都应该封装在需要它们完成工作的类中。
我更喜欢使用getter而不是常量。这些getter可能返回常量值,例如public int getMaxConnections() {return 10;},但任何需要常量的东西都将通过getter。
一个好处是,如果您的程序超出了常量的使用范围——您发现它需要可配置——您可以更改getter返回常量的方式。
另一个好处是,为了修改常量,你不必重新编译所有使用它的东西。当引用静态final字段时,该常量的值将被编译到引用它的任何字节码中。
在单独的类中创建静态final常量可能会给您带来麻烦。Java编译器实际上会对此进行优化,并将常量的实际值放置到引用它的任何类中。
如果你稍后更改了Constants类,并且没有对引用该类的其他类进行严格的重新编译,那么你最终将使用新旧值的组合。
不要把它们看作常量,而应该把它们看作配置参数,并创建一个类来管理它们。让值是非final的,甚至可以考虑使用getter。将来,当您确定其中一些参数实际上应该由用户或管理员进行配置时,这将变得容易得多。
仅仅为了保存常量而使用接口是一种糟糕的做法(Josh Bloch将其命名为常量接口模式)。以下是乔希的建议:
如果常数与 现有的类或接口 是否应该将它们添加到类中 接口。例如,所有的 盒装的数字基元类, 如Integer和Double,导出 MIN_VALUE和MAX_VALUE常量。如果 这些常数最好看成 枚举类型的成员 应该用enum导出它们吗 类型。否则,您应该导出 带有不可实例化对象的常量 实用程序类。
例子:
// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
private PhysicalConstants() { } // Prevents instantiation
public static final double AVOGADROS_NUMBER = 6.02214199e23;
public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
public static final double ELECTRON_MASS = 9.10938188e-31;
}
关于命名约定:
按照惯例,这些字段有名称 由大写字母组成的 用下划线分隔的单词。它是 重要的是,这些字段包含 要么是原始值,要么是引用 到不可变对象。