我最近询问过从另一个班级获取班级的唯一实例。
(How to get specific instance of class from another class in Java?)
所以,我正努力让它发挥作用:
我的Application
:
public class Application
{
// I will always have only one instance of Application
private static Application _application;
// Every instance of Application (one in my case) should have its own View
private View view;
// Constructor for new instance of Application
private Application()
{
view = new View();
}
// Getter for my unique instance of Application
public static Application getSharedApplication()
{
if (_application == null)
_application = new Application();
return _application;
}
// Main class
public static void main(String[] args)
{
// So I'm accessing my instance of Application
Application application1 = getSharedApplication();
// Here is object reference
System.out.println(application1);
// And now I'm accessing the same instance of Application through instance of View
Application application2 = application1.view.getApplication();
// Here is object reference
System.out.println(application2);
}
}
我的View
:
public class View
{
// I'm accessing my instance of Application again
public static Application application = Application.getSharedApplication();
// This method should return my unique instance of Application
public Application getApplication()
{
return application;
}
}
问题是main
方法返回不同的对象引用。
Application@1430b5c
Application@c2a132
我的代码出了什么问题?
答案 0 :(得分:7)
以下是发生的事情:
Application application1 = getSharedApplication();
new Application()
的静态方法 - 该调用需要加载View类,该类是Application
的成员。getSharedApplication();
(请注意,在此阶段,_application
仍为null)。这也会产生new Application()
您现在有2个应用程序实例。
请注意,如果添加View v = new View();
作为main的第一行,则只有一个Application实例(从View的静态变量加载一次)。当你仔细思考但不是很直观时,这是有道理的......
答案 1 :(得分:4)
这些问题的一般答案是:使用调试器!例如,您可以在Application
的构造函数中设置断点,运行程序,并在构造函数第二次执行时检查堆栈。
如果你这样做,你会注意到这样的事情:
Application.<init>() line: 21
Application.getSharedApplication() line: 31
View.<clinit>() line: 59
Application.<init>() line: 23
Application.getSharedApplication() line: 31
也就是说,视图想要在共享应用程序完全构建之前(并且在后者存储在静态字段中之前)获取共享应用程序。
答案 2 :(得分:1)
如果您更改View的初始化,如下所示
public static Application getSharedApplication() {
if(_application == null)
{
_application = new Application();
view = new View();
}
您将发现只创建了一个实例。 原因是您在Application完全初始化之前创建了View实例。因为第一次请求类时会加载静态变量,所以会发生这种情况。
无论如何,我知道从来没有这样做:)谢谢:)
答案 3 :(得分:0)
getSharedApplication()方法应该使用synchronized关键字。否则,两个线程可能会进入第一个if语句块,并且都会创建不同的变量。
我不确定这是不是这里发生了什么。尝试在任何地方添加调试/打印语句,以便您可以关注实际发生的事情。