在哪里定义Java中几个不相关类中使用的常量
在Java中在何处定义常量的问题已经在论坛上多次出现,但我仍在努力找到一个我感到满意的解决方案 为了简单起见,假设我有两个类:在哪里定义Java中几个不相关类中使用的常量,java,enums,constants,Java,Enums,Constants,在Java中在何处定义常量的问题已经在论坛上多次出现,但我仍在努力找到一个我感到满意的解决方案 为了简单起见,假设我有两个类:WriteMyData和ReadMyData。没有一个是另一个的子类。这两个类共享两个对其操作至关重要的常量:String DELIMITER和int LENGTH。将来我可能想更改这些常量的值,以便在适当的位置定义它们 人们的共识似乎往往倾向于enum类型。但是,在我的例子中没有什么可枚举的,因此我在我的enum中只有一个项目,我称之为DEFAULT: public e
WriteMyData
和ReadMyData
。没有一个是另一个的子类。这两个类共享两个对其操作至关重要的常量:String DELIMITER
和int LENGTH
。将来我可能想更改这些常量的值,以便在适当的位置定义它们
人们的共识似乎往往倾向于enum
类型。但是,在我的例子中没有什么可枚举的,因此我在我的enum
中只有一个项目,我称之为DEFAULT
:
public enum DataSettings {
DEFAULT(",", 32);
private final String delimiter;
private final int length;
DataSettings(String delmiter, int length) {
this.delimiter = delimiter;
this.length = length;
}
public String getDelimiter() { return delimiter; }
public int getLength() { return length; }
}
因此,在我的两个类中,我都通过DataSettings.DEFAULT.getDelimiter()
和DataSettings.DEFAULT.getLength()
访问常量
这真的是好的OO风格吗?
enum
的使用是否过度了?如果我不使用enum
,我应该怎么做?为常量创建接口似乎不受欢迎,而且我的类似乎没有可以派生的自然超类。在enum
中只有一个默认项是初学者的错误吗?如果只有这两个常量,并且没有更多的常量,那么您可以有一个类似
interface DataSetting
{
String DELIMITER = ",";
int LENGTH = 32;
}
如果需要通过属性初始化
public class DataSetting {
public static String DELIMITER = ",";
public static int LENGTH = 32;
static {
DELIMITER = System.getProperty("delimiter");
LENGTH = Integer.parseInt(System.getProperty("length"));
// or from config
}
}
只有1个值的枚举可能没有多大意义,但如果您计划扩展它可能包含的任何值,它可能会很有用 您所说的另一种方法是如下操作:
和defaultvalues
。这些方法将依次调用其他方法并传入默认参数作为旁注,简单地重载您已有的方法可能是有意义的,这样您就有了一个默认为这些常量的实现。如果是这种情况,请确保在方法的签名中记录这一点。只需创建类似于
Constants.java的类,您将在其中放置所有常量
例如:
public class Constants {
public static final String DELIMITER = "-";
public static final int LENGTH = 1;
}
并在需要的地方使用它们,方法是:
Constants.DELIMITER
Constants.LENGTH
依我看,在这种情况下,Enum是过分的。用于枚举
对于全局常量,您只需在java类或java接口中创建一个公共静态final类属性,尽管最新的方法不是通常的方法(请参见)我将提出另一种解决方案,它不使用WriteMyData
和ReadMyData
中的任何常量
不要将分隔符和长度作为构造函数参数传递。通过这种方式,您将能够使用参数对这些类进行单元测试,从而使测试更加容易
当每个的实例使用相同的delimiter和length值非常重要时,应该在同一位置实例化这两个值,并使其可供客户端使用。创建实例的位置是一个适当的位置,可以为分隔符和长度值设置常量。您可以创建一个接口。
默认情况下,接口中的常量是静态的和最终的。
您可以通过引用接口来使用这些变量
public interface AnyNameInterface {
String AnyVar ="DEMO";
Double AnyVar_2 = 123.00;
}
用作:
AnyNameInterface.AnyVar
AnyNameInterface.AnyVar_2
在没有什么可枚举的情况下使用enum
,确实是一种不好的做法
提到的另一种选择,使用接口
也是一个糟糕的选择。有效Java,第19项对其进行了最佳描述:
Item19:仅使用接口定义类型
当一个类实现一个接口时,该接口充当一个类型,可用于引用该类的实例。因此,类实现接口应该说明客户端可以对类的实例做什么。为任何其他目的定义接口是不合适的
一种未通过此测试的接口是所谓的常量接口。这样的接口不包含任何方法;它仅由静态final字段组成,每个字段导出一个常量。使用这些常量的类实现接口,以避免使用类名限定常量名称
正确的实现是定义一个不可实例化的实用程序类:
public class Constants {
private Constants(){} // Private constructor prevents instantiation AND subclassing
public static final String DELIMITER = "-";
public static final int LENGTH = 1;
}
为方便起见,您可以静态导入代码中的常量:
import static com.example.Constants.*;
public class Test {
public static void main(String[] args){
System.out.println(DELIMITER); // prints "-"
}
}
我想补充一点,即使有一些东西需要枚举,枚举也不能总是用作常量的容器,即使它们很好
例如,javax.ws.rs.Path定义了一个字符串类型的注释类型元素。但是,这不会编译:
@Path(MyEnum.BASE\u Path)
也不会
@Path(MyEnum.BASE\u Path.name())
此外,在无法在类本身或某个公共超类上定义常量的情况下,讨论通常是在类中定义常量与在接口中定义常量之间进行的。第三种选择是在注释中定义它们
public @interface MyAnnotation {
String QUESTIONS = "/questions";
String ANSWERS = "/answers"; }
注释方法避开了“恒定界面”的陷阱。据我所知,这个陷阱并不是说接口本身作为一个常量容器是个坏主意,-问题是调用方决定实现接口时,不要通过静态导入等方式访问常量。如果没有可枚举的内容(即只有一个数据设置),只需将其设置为一个静态类,并将分隔符和长度作为公共静态最终变量。这两个变量是否指向相同的值?您想在一个位置声明常量变量吗?理想情况下,是