在Java中从配置文件读取配置参数的最佳方法是什么?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (25)

让我们假设到运行时,我们不知道配置的细节(用户可能需要在config在运行应用程序之前将文件归档。

我希望阅读这些配置细节,并在应用程序中需要它们的任何地方重用它们。为此,我想将它们作为全局常量(public static final)

所以,我怀疑,如果我读到config直接从所需的类?开始,运行时值我不能直接放在单独的Interface...

我认为这会影响成绩,请给我建议更好的方法。

最新情况:我是否可以使用单独的最终类来处理配置细节?将所有配置细节作为常量放在单独的public final class

(从配置文件中一次读取所有配置细节,并将其存储为全局常量,供以后在应用程序中使用)

提问于
用户回答回答于

我认为它会影响性能。

我怀疑这是否属实。

假设应用程序在启动时仅读取一次配置文件,读取文件所需的时间可能与应用程序的整体性能无关。事实上,应用程序运行时间越长,启动时间就越不重要。

标准的建议是,只有在您有具体的证据(即测量数据)表明性能一个重大问题时才对应用程序性能进行优化。然后,只优化代码的那些部分,分析表明它确实是性能瓶颈。

我可以使用单独的最终课程来获取配置细节

是的,有可能做到这一点。没有人会阻止你1。但是,这是一个糟糕的主意。任何意味着您需要重新编译代码来更改配置参数的想法都是一个坏主意。IMO。

从配置文件中一次性读取所有配置细节,并将它们存储为全局常量,以备将来在应用程序中使用。

啊......所以想要读取“常数”的值而不是硬连线它们。

是的,那是可能的。这比将配置参数硬编码到代码中更有意义。但它仍然不是一个好主意(海事组织)。

为什么?那么让我们来看看代码的外观:

public final class Config { 
    public static final int CONST_1;
    public static final String CONST_2;

    static {
        int c1;
        String c2;
        try (Scanner s = new Scanner(new File("config.txt"))) {
            c1 = s.nextInt();
            c2 = s.next();
        } catch (IOException ex) {
            throw RuntimeException("Cannot load config properties", ex);
        }
        CONST_1 = c1;
        CONST_2 = c2; 
    }
}

首先观察的是,这个阶级是没有区别的final。据宣布领域final,使他们不断。(将类声明为final禁止子类化,但对static字段没有影响。静态字段不受继承的影响。)

接下来的观察是,这个代码在很多方面都很脆弱:

  • 如果在静态初始化块中出现问题。该块引发的未经检查的异常将被包装为ExceptionInInitializerError(是...它是Error!!),并且Config该类将被标记为错误。
  • 如果发生这种情况,恢复就没有现实的希望了,尝试和诊断问题甚至可能是一个坏主意Error
  • 上面的代码在Config类被初始化时被执行,但是确定何时发生这种情况可能会非常棘手。
  • 如果配置文件名是一个参数,那么在触发静态初始化之前,您有问题获取参数值...。

接下来,与将状态加载到实例变量相比,代码非常麻烦。而这种混乱主要是由于必须在静态初始化器的约束条件下工作。如果您使用final实例变量,代码如下所示。

public final class Config { 
    public final int CONST_1;
    public final String CONST_2;

    public Config(File file) throws IOException {
        try (Scanner s = new Scanner(file)) {
            CONST_1 = s.nextInt();
            CONST_2 = s.next();
        } 
    }
}

最后,static final字段在final字段上的性能优势很小:

  • 每次访问其中一个常量时可能会有一两个机器指令,
  • 如果JIT编译器很聪明,那么可能什么也没有,并且Config适当地处理单例引用。

无论哪种情况,在绝大多数情况下,好处都是微不足道的。

用户回答回答于

你有没有听说过Apache公共配置http://commons.apache.org/proper/commons-configuration/?这是我见过的最好的配置读卡器,甚至可以在我的应用程序中使用它,该应用程序自1年以来一直在运行。从未发现任何问题,非常容易理解和使用,性能卓越。我知道它对你的应用程序有一点依赖性,但相信我你会喜欢它。

你所需要做的就是

Configuration config = new ConfigSelector().getPropertiesConfiguration(configFilePath);
String value = config.getString("key");
int value1 = config.getInt("key1");
String[] value2 = config.getStringArray("key2");
List<Object> value3 = config.getList("key3");

那就是它。您的配置对象将保存所有配置值,您可以将该对象传递给任意多个类。有了这么多可用的有用的方法,你可以提取你想要的任何类型的密钥。

扫码关注云+社区