使Singleton Class对象的实例符合GC

时间:2015-07-14 05:41:43

标签: java enums jaxb garbage-collection singleton

我有一个类JAXBReader,它使用jaxb生成的类来保存unmarshalled xml文件。我使用了单例设计,所以我不需要一次又一次地解组文件。这个类的对象(恰好是unmarshalled xml)只需要初始化一个有八个常量的枚举。枚举常量的构造函数使用单例对象来获取xml所需的部分。

初始化枚举后,我的系统中不需要JAXBReader的objetc。我怎样才能做到这一点?

我读了here我可以调用setter来为静态singelton实例赋值null,但我不想在外部执行它。我想要的是,在初始化枚举后,实例被自动赋值为空。

我正在使用Java 1.7

2 个答案:

答案 0 :(得分:2)

一种选择是在枚举的静态初始值设定项中完成所有这些操作。在枚举本身中保留一个静态字段,编写一个私有静态方法来获取文件的内容,必要时读取它,然后在枚举初始化结束时 - 在静态初始化程序块中 - 将其设置为null:

public enum Foo {
    VALUE1, VALUE2, VALUE3;
    private static JAXBReader singleReader;

    static {
        singleReader = null; // Don't need it any more
    }

    private Foo() {
        JAXBReader reader = getReader();
        // Use the reader
    }

    private static JAXBReader getReader() {
        // We don't need to worry about thread safety, as all of this
        // will be done in a single thread initializing the enum
        if (singleReader == null) {
            // This will only happen once
            singleReader = new JAXBReader(...);
        }
        return singleReader;
    }
}

这样只有 enum 知道读者是单身人士 - 无论何时你喜欢外部,你仍然可以创建一个新的JAXBReader,这对测试非常有用。

(我有点担心枚举初始化需要外部资源开始,但我可以看到它可能很难避免。)

答案 1 :(得分:0)

使用WeakReference来保留您的对象。

private static WeakReference<JAXBReader> instance = null;

public static JAXBReader getInstance() {
    if (instance.get() == null) {
        instance = new WeakReference(new JAXBReader());
    }
    return instance.get();
}

这样,如果没有其他参考,那么它将被GC编辑。