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

在Java中初始化复杂静态成员的最佳方法是什么?

在Java中初始化复杂静态成员的最佳方法是什么?,java,static-members,Java,Static Members,我的目标是在我的类中有一个私有的静态属性对象,在创建我的应用程序所需的其他属性对象时充当默认对象。当前的实现如下所示: public class MyClass { private static Properties DEFAULT_PROPERTIES = new Properties(); static { try { DEFAULT_PROPERTIES.load( MyClass.class.getRe

我的目标是在我的类中有一个私有的静态
属性
对象,在创建我的应用程序所需的其他
属性
对象时充当默认对象。当前的实现如下所示:

public class MyClass {
    private static Properties DEFAULT_PROPERTIES = new Properties();

    static {
        try {
           DEFAULT_PROPERTIES.load(
               MyClass.class.getResourceAsStream("myclass.properties"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
 }
看着它,它工作了,但感觉不对


你会怎么做?

我似乎可以接受;在静态初始化器中加载时,只在引用类时调用它,并且只调用一次。我喜欢。我唯一要做的就是把它定为最终版本


嗯,除了例外。我会尝试以某种方式避免这种情况(我的想法是,您应该避免在这些类型的初始化器中出现异常,但我可能在这一点上是错误的)。

我会抛出一个异常,而不是一般的运行时异常,这正是出于此目的。来自API文档:“表示静态初始值设定项中发生意外异常。”

基本上有两种方法。第一种方法是使用如图所示的静态块(但随后使用一个而不是
运行时异常
)。第二种方法是使用静态方法,在声明时立即调用该方法:

private static Properties DEFAULT_PROPERTIES = getDefaultProperties();

private static Properties getDefaultProperties() {
    Properties properties = new Properties();
    try {
        properties.load(MyClass.class.getResourceAsStream("myclass.properties"));
    } catch (IOException e) {
        throw new ConfigurationException("Cannot load properties file", e);
    }
    return properties;
}
ConfigurationException
可以是扩展
RuntimeException
的自定义类

我个人更喜欢
静态
块,因为在它的生命周期中只有一次执行的方法是没有意义的。但是,如果您重构该方法,使其具有文件名并可以全局重用,那么这将是更可取的

private static Properties DEFAULT_PROPERTIES = SomeUtil.getProperties("myclass.properties");

// Put this in a SomeUtil class.
public static Properties getProperties(String filename) {
    Properties properties = new Properties();
    try {
        properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(filename));
    } catch (IOException e) {
        throw new ConfigurationException("Cannot load " + filename, e);
    }
    return properties;
}

哦,我不知道。谢谢你的提示@jarnbjo我认为如果你提供一个指向API文档(ExceptionInitializer)的链接也会很有帮助:@sateesh:如果Java开发人员在API文档中找不到一个类,而我的答案中没有链接,那么他是时候学习如何做了。这实际上符合我的问题,因为我将创建更多具有相同模式的类,因此,创建一个抽象类并用
getProperties()
方法填充它是有意义的,这样它就可以在我的所有子类中重用。非常有用,谢谢!注意,我使用
Thread\getContextClassLoader()
更改了加载属性文件的方式。别忘了在代码中也修改它。这会不会将资源加载到调用
getProperties()
的类的同一个包中?我不确定是否理解您的意思。任何一种方式都是独立于包的。您可以在文件名中指定包。改进的方法只是类独立的,并且利用了已经加载调用类的类加载器。通过这种方式,您可以确保资源永远不会返回null,如果调用类没有被线程的类加载器加载,则可能会发生这种情况。我指的是
org.example.MyClass.class.getResourceAsStream(“MyClass.properties”)
将打开资源
ROOT/org/example/MyClass.properties
,使用
ClassLoader
时,它将在
ROOT/
目录中查找资源。我错了吗?