类中的静态类实例

时间:2015-12-17 16:12:38

标签: java static

我很难理解静态类在以下场景中的使用方式。

假设我按如下方式声明了一个类:

public class TestLibrary {

    private static final TestLibrary library = new TestLibrary();
    private ErrorHandler errorHandler = null;

    public static TestLibrary getLibrary() {
        return library;
    }
    public ErrorHandler getErrorHandler() {
        return errorHandler;
    }

    public int run(String[] args) {
        this.initialize(args);
    }

    private void initialize(String[] data) {
        library.errorHandler = new ErrorHandler();
    }   
}

我现在稍微将班级改为

private void initialize(String[] data) {
    errorHandler = new ErrorHandler();
}

我在其他类中声明errorHandler,如下所示:

private ErrorHandler errorHandler = TestLibrary.getLibrary().getErrorHandler();

当我在其他类中使用errorHandler的实例时,我的代码最终仍然起作用,但我不明白为什么。

问题1:第二种情况不应该创建new ErrorHandler作为对象TestLibrary.errorHandler而不是library.errorHandler的一部分吗?

问题2:我做错了吗?你能详细说明一下吗?

1 个答案:

答案 0 :(得分:0)

你所拥有的是一个静态方法getLibrary(),它为所有调用者返回相同的实例。这被称为 Singleton - 虽然有更好的方法来编码它们。

然后你的假设Singleton(TestLibrary)展示了当被称为改变内部状态时的方法 - 最重要的是ErrorHandler

这会导致奇怪的行为,尤其是在多线程系统中。

这样的代码:

TestLibrary.getLibrary().run("".split(""));
ErrorHandler eh = TestLibrary.getErrorHandler();
assertEquals(eh, TestLibrary.getErrorHandler());

可能会失败。因为某人(意思是:某些其他线程)可能刚刚在第2行和第3行之间调用init(),导致ErrorHandler被设置为另一个值。

如果你需要在使用之前初始化你的TestLibrary,你应该一次,只做一次 - 所以你最好把它放到TestLibrary的构造函数中

如果您需要在代码中初始化不同的TestLibraries,则应删除Singleton模式并坚持使用

  TestLibrary tl = new TestLibrary();
  tl.run("".split(""));

What is an efficient way to implement a singleton pattern in Java?

中详细了解Singleton