Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在哪里定义Java中几个不相关类中使用的常量_Java_Enums_Constants - Fatal编程技术网

在哪里定义Java中几个不相关类中使用的常量

在哪里定义Java中几个不相关类中使用的常量,java,enums,constants,Java,Enums,Constants,在Java中在何处定义常量的问题已经在论坛上多次出现,但我仍在努力找到一个我感到满意的解决方案 为了简单起见,假设我有两个类:WriteMyData和ReadMyData。没有一个是另一个的子类。这两个类共享两个对其操作至关重要的常量:String DELIMITER和int LENGTH。将来我可能想更改这些常量的值,以便在适当的位置定义它们 人们的共识似乎往往倾向于enum类型。但是,在我的例子中没有什么可枚举的,因此我在我的enum中只有一个项目,我称之为DEFAULT: public e

在Java中在何处定义常量的问题已经在论坛上多次出现,但我仍在努力找到一个我感到满意的解决方案

为了简单起见,假设我有两个类:
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"; }
    

    注释方法避开了“恒定界面”的陷阱。据我所知,这个陷阱并不是说接口本身作为一个常量容器是个坏主意,-问题是调用方决定实现接口时,不要通过静态导入等方式访问常量。

    如果没有可枚举的内容(即只有一个数据设置),只需将其设置为一个静态类,并将分隔符和长度作为公共静态最终变量。这两个变量是否指向相同的值?您想在一个位置声明常量变量吗?理想情况下,是