Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.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_Io - Fatal编程技术网

Java-如何选择一个可用路径来加载静态块中的文件?

Java-如何选择一个可用路径来加载静态块中的文件?,java,io,Java,Io,我的类中有一个静态块,因此当类加载器加载类定义时,将从该静态块调用一个方法。该方法的目的是从一个可用路径加载配置。我希望使用第一个可用路径 共有2个配置文件(metrics\u config.json,metrics\u config\u new.json),每个文件都可以位于以下两个路径之一: private static final File CONFIG_FILE_1 = new File("file:///dest1/config/metrics_config.json"); priva

我的类中有一个静态块,因此当类加载器加载类定义时,将从该静态块调用一个方法。该方法的目的是从一个可用路径加载配置。我希望使用第一个可用路径

共有2个配置文件(
metrics\u config.json
metrics\u config\u new.json
),每个文件都可以位于以下两个路径之一:

private static final File CONFIG_FILE_1 = new File("file:///dest1/config/metrics_config.json");
private static final File CONFIG_FILE_2 = new File("file:///dest2/config/metrics_config.json");

private static final File CONFIG_FILE_3 = new File("file:///dest1/config/metrics_config_new.json");
private static final File CONFIG_FILE_4 = new File("file:///dest2/config/metrics_config_new.json");
如何只传递当前可用于该方法的一条路径?我想这可能与此类似:

static {
    // choose 1st file's path
    if (CONFIG_FILE_1.exists() && CONFIG_FILE_1.isFile()) {
        loadConfiguration(CONFIG_FILE_1);
    }
    if (CONFIG_FILE_2.exists() && CONFIG_FILE_2.isFile()) {
         loadConfiguration(CONFIG_FILE_2);
    }
    // choose 2nd file's path
    if (CONFIG_FILE_3.exists() && CONFIG_FILE_3.isFile()) {
         loadConfiguration(CONFIG_FILE_3);
    }
    if (CONFIG_FILE_4.exists() && CONFIG_FILE_4.isFile()) {
         loadConfiguration(CONFIG_FILE_4);
    }
}
我当前解决方案的缺点是,它将检查第一个文件和第二个文件的两个路径。
确定传递给
loadConfiguration
方法的路径的正确方法是什么?

如果要执行类似操作,可以使用
else:

static {
    // choose 1st file's path
    if (CONFIG_FILE_1.exists() && CONFIG_FILE_1.isFile()) {
        loadConfiguration(CONFIG_FILE_1);
    }
    else if (CONFIG_FILE_2.exists() && CONFIG_FILE_2.isFile()) {
         loadConfiguration(CONFIG_FILE_2);
    }
    // choose 2nd file's path
    if (CONFIG_FILE_3.exists() && CONFIG_FILE_3.isFile()) {
         loadConfiguration(CONFIG_FILE_3);
    }
    else if (CONFIG_FILE_4.exists() && CONFIG_FILE_4.isFile()) {
         loadConfiguration(CONFIG_FILE_4);
    }
}
在最好的情况下,这意味着只需检查两条路径,但在最坏的情况下,仍需检查所有路径

为了避免代码重复,最好创建一个单独的方法来获取正确的文件

public static File fetchConfigFile(file1, file2) {
    if (file1.exists() && file1.isFile()) {
        return file1;
    }
    else if (file2.exists() && file2.isFile()) {
         return file2;
    }
    // Be aware: returning null might not be what you want. 
    return null;
}
静态
块可以简化为:

static {
    loadConfiguration(fetchConfigFile(CONFIG_FILE_1, CONFIG_FILE_2));
    loadConfiguration(fetchConfigFile(CONFIG_FILE_3, CONFIG_FILE_4));
}

解决这一问题的办法实际上是不这样做。没有或其他类初始化代码执行由于IO等环境问题(使用类加载器除外)而很有可能失败的操作

  • 这样做时确保良好的错误处理非常困难,这意味着,IO代码中的错误处理必须是自包含的
  • 这使得使用依赖注入进行单元测试非常困难
  • 。如果您的代码很复杂,这使得那些
    静态
    块之间的依赖关系很难正确处理。正确地执行IO是复杂的
  • 保持锁定时执行
    静态
    块。如果
    static
    块直接或间接尝试执行任何多线程处理,则可能导致死锁。例如,通过。避免此类问题的唯一方法是使块中的代码非常简单。正如我之前所说,IO代码是复杂的。它不可避免地涉及到以一种复杂且不明显的方式委托给其他类(封装和信息隐藏是一种特性,而不是bug)。你能确定所有封装的代码都不会导致死锁吗
  • 重要的是,在卸载相应的类加载器之前,静态对象引用不会被垃圾收集。因此,当引用指向外部资源时,可能的内存泄漏可能会造成严重的影响

相反,将读取的配置文件移动到
main
方法或从中调用的方法中。

使用If..Else条件必须声明
fetchConfigFile
方法才能在静态块中调用。谢谢,我已更改了它。