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

标签 java oop configuration initialization runtime

让我们假设到运行时我们不知道配置的细节是什么(可能用户需要在运行应用程序之前在 config 文件中配置这些参数。

我想阅读这些配置详细信息,并且需要在我的应用程序中任何需要它们的地方重复使用它们。为此,我想将它们设为全局常量(public static final)。

所以,我的疑问是,如果我直接从所需的类中读取 config 文件,是否会对性能产生影响?因为,运行时值我不能直接放在单独的 Interface 中。

我认为它会影响性能。请给我建议任何更好的方法来做到这一点。

更新:我可以使用单独的最终类来获取配置详细信息吗? 将所有配置细节作为常量放在一个单独的 public final class
(一次从配置文件中读取所有配置细节并将它们存储为全局常量以供以后在应用程序中使用)

最佳答案

I am thinking it will impact performance.

我怀疑这是真的。

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

标准建议是仅在您有具体证据(即测量结果)表明性能是一个重要问题时才优化应用程序性能。然后,只优化分析告诉您的代码部分确实是性能瓶颈。


Can I use separate final class for configuration details

是的,可以这样做。没有人会阻止你1。 然而,这是一个坏主意。任何意味着您需要重新编译代码以更改配置参数的事情都是一个坏主意。国际海事组织。


To read all configuration details at once from the configuration file and storing them as global constants for later use in application.

啊......所以你实际上想读取“常量”的值而不是硬连线它们。

是的,这是可能的。而且它比将配置参数硬连接到代码中更有意义。但这仍然不是一个好主意(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 并没有什么区别。它将 fields 声明为 final 使它们保持不变。 (将类声明为 final 可防止子类化,但这对 static 字段没有影响。静态字段不受继承影响。)

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

  • 如果静态初始化程序 block 出现问题。 block 抛出的未经检查的异常将被包装为 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 引用,则可能什么都没有。

在任何一种情况下,绝大多数情况下的好处都是微不足道的。


1 - 好的...如果您的代码经过代码审查,那么有人可能会阻止您。

关于java - 从 Java 配置文件中读取配置参数的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26908854/

相关文章:

PHP 不存储 session ID

angularjs - 全局配置 Angular 指令

configuration - 通过 Hadoop 配置对象从 InputFormat 返回值

java - system.out 之后的 hibernate 代理对象

java - Kafka 不会从 PEM 证书开始

ios - 将在整个应用程序或类(class)中使用的颜色

java - 多个 Java Web 应用程序的自动化部署解决方案

java - 在mysql查询期间java代码中进行一些迭代后出现无限循环 "hangs"

java - 如何在单击按钮时暂停 android 中的 Httpurl 连接

java - 这里面有什么设计模式吗?这个java代码有什么可能的缺陷吗?