实现一类"常数"在应用程序启动时初始化而不是在编译时

时间:2014-12-30 14:53:02

标签: java singleton constants

我正在开发一个使用大类常量的Java项目,如:

public final class Settings {
    public static final int PORT_1 = 8888;
    public static final int PORT_2 = 8889;
    ...
}

现在,这些常量的某些值在编译时不再可用,所以我需要一种方法来初始化"它们在应用程序启动时(例如来自args [])。一旦初始化,就没有办法改变它们。我在java方面不是很熟练,我该如何以可接受的方式做到这一点?

我想过使用一个像一个"一个镜头" set方法如果多次调用会引发异常,但它接缝太乱了......

3 个答案:

答案 0 :(得分:3)

你可以使用这样的静态初始化器:

public final class Settings {
  public static final int PORT_1;
  public static final int PORT_2;
  ...

  static {
    // create the value for PORT_1:
    PORT_1 = ...;
    // create the value for PORT_2:
    PORT_2 = ...;
  }
}

静态初始化程序在类加载期间执行。 PORT_1PORT_2上的最终关键字可以保护它们随后更改。

答案 1 :(得分:2)

好吧,使用系统属性是一种方法,除非有大量的常量。

private static final String CONSTANT1 = System.getProperty("my.system.property");
private static final int CONSTANT2 = Integer.valueOf(System.getProperty("my.system.property"));

使用-D标志启动应用程序时,系统属性在命令行上传递。

如果太多许多变量,可以使用静态初始化程序,其中可以读取包含属性的属性文件或类似文件:

public class Constants {
    private static final String CONSTANT1 = System.getProperty("my.system.property");
    private static final int CONSTANT2 = Integer.valueOf(System.getProperty("my.system.property"));
    private static final String CONSTANT3;
    private static final String CONSTANT4;

    static {
        try {
            final Properties props = new Properties();
            props.load(
                new FileInputStream(
                        System.getProperty("app.properties.url", "app.properties")));

            CONSTANT3 = props.getProperty("my.constant.3");
            CONSTANT4 = props.getProperty("my.constant.3");
        } catch (IOException e) {
            throw new IllegalStateException("Unable to initialize constants", e);
        }
    }
}

请注意,如果您使用的是某些外部框架(如Spring Framework或类似框架),则通常会有内置机制。例如。 - Spring Framework可以通过@Value注释从属性文件中注入属性。

答案 2 :(得分:1)

在Java中没有简单的方法可以做到这一点。模拟这种情况的一种方法是使用一个返回内部类型的构建器(因此它可以编写私有字段),但内部类型只有getter。

请参阅此答案:https://stackoverflow.com/a/1953567/34088