【问题标题】:Static class instance inside class类中的静态类实例
【发布时间】:2015-12-17 16:12:37
【问题描述】:

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

假设我声明一个类如下:

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:我做错了吗?能详细点吗?

【问题讨论】:

  • 我感觉你想让TestLibrary 成为单身人士,但不知道该怎么做。
  • 使用library.errorHandler = new ErrorHandler(),您将始终更改libraryerrorHandler 引用的对象。使用errorHandler = new ErrorHandler();,您将更改this 对象的errorHandler
  • @jan Sotirios 是正确的。 ErrorHandler 中没有导入。
  • 您正在展示一个在同一类的实例上具有 getter 的类。为什么不直接使用构造函数?
  • @Sotirios Delimanolis 所以,这证实了我的怀疑。它正在更改不同的对象ErrorHandler。谢谢。

标签: java static


【解决方案1】:

你有一个静态方法getLibrary(),它为所有调用者返回相同的实例。这被称为 Singleton - 尽管有更好的编码方式。

然后,您假定的 Singleton (TestLibrary) 再次展示了在调用时更改内部状态的方法 - 最重要的是 ErrorHandler

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

这样的代码:

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

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

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

如果您需要在整个代码中初始化不同的 TestLibraries,您应该删除单例模式并坚持使用普通模式

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

What is an efficient way to implement a singleton pattern in Java?了解更多关于 Singleton 的信息

【讨论】:

  • 推测会有很多线程使用,但TestLibrary 的每个实例将使用不同的参数进行初始化。在“库”中,许多对象引用了errorHandler 的同一个实例。谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-02-14
  • 1970-01-01
  • 2014-04-27
  • 2010-10-25
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多