我认为这会影响性能。
我怀疑这不是真的。
假设应用程序在启动时只读取一次配置文件,则读取文件所需的时间可能与应用程序的整体性能无关。实际上,应用程序运行的时间越长,启动时间就越不重要。
标准建议是仅在具有确凿证据(即测量)表明性能是一个重大问题时才优化应用程序性能。然后,仅优化那些分析告诉您真正成为性能瓶颈的代码部分。
我可以使用单独的final类作为配置详细信息吗?
是的,这是可能的。没有人会阻止你1。然而,这是一个坏主意。任何导致需要重新编译代码以更改配置参数的操作都是一个坏主意。依我看。
从配置文件一次性读取所有配置详细信息,并将它们存储为全局常量,以供应用程序稍后使用。
啊... 所以您实际上想要读取“常量”的值,而不是硬编码它们。
是的,这是可能的。它比将配置参数硬编码到代码中更有意义。但这仍然不是一个好主意(依我看)。
为什么?让我们看看代码应该是什么样子:
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
才会使它们成为常量。 (将类声明为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
字段相比在性能上的优势微乎其微:
无论如何,在绝大多数情况下,这些优势都是微不足道的。
1 - 如果您的代码经过代码审查,那么可能会有人阻止您这样做。