我无法理解我遇到的一段代码。
以下是一段类似的代码:
class GrandParent
{
private Map<String, String> map = new HashMap<String, String>();
protected void insertString(String key, String value)
{
map.put(key, value);
}
}
abstract class AbstractParent extends GrandParent
{
private static AbstractParent parent1;
public static AbstractParent getParent1Instance()
{
if(parent1 == null)
{
parent1 = new ImplementingChild();
}
return parent1;
}
public void populateStringMapInitial()
{
for(int count = 0; count < 10; count++)
{
insertString("" + count, "parent count value = "+count);
}
}
public void populateStringMapNext()
{
for(int count = 10; count < 20; count++)
{
insertString("" + count, "parent count value = "+count);
}
}
}
class ImplementingChild extends AbstractParent
{
public void populateStringMapInitial()
{
for(int count = 0; count < 10; count++)
{
insertString("" + count, "child count value = "+count);
}
}
public void populateStringMapNext()
{
for(int count = 10; count < 20; count++)
{
insertString("" + count, "child count value = "+count);
}
}
}
如果通过子项创建AbstractParent的静态实例,'map'变量的范围是多少? Map是GrandParent的私有(即在对象级别),AbstractParent的对象是静态的(即在类级别)。可以吗? 即使AbstractParent(Child)实例存在,'map'变量是否有资格进行垃圾收集?
其次,这种设计背后的原因可能是什么?
我测试了前面提到的代码,以便对AbstractParent的静态实例进行非静态引用,如下例所示:
class AbstractAndStaticTest {
public static void main(String[] args)
{
AbstractParent parent1 = AbstractParent.getParent1Instance();
parent1.populateStringMapInitial();
parent1 = null;
AbstractParent parent2 = AbstractParent.getParent1Instance();
parent2.populateStringMapNext();
System.out.println();
}
}
发现地图中包含了所有20个元素。任何人都可以解释这背后的原因吗?我想我错过了一些非常基本的东西。
答案 0 :(得分:1)
我想我错过了一些非常基本的东西。
非常基本的事情。静态变量或其他所述类级变量在类的所有实例之间共享。所以你只有一个类级变量实例:
private static AbstractParent parent1;
并且AbstractParent.getParent1Instance()
的每个请求都会返回一个并且始终是同一个实例。
您在main中的方法级声明:
AbstractParent parent1
不会改变任何东西,因为它在完全方法本地和完全不同的类AbstractAndStaticTest中,所以parent1 = null只使AbstractParent实例符合垃圾收集条件,但不符合Class对象而不是Class级实例,因为它们从未符合条件对于GC。
答案 1 :(得分:0)
因为你的代码是:
AbstractParent parent2 = AbstractParent.getParent1Instance();
parent2.populateStringMapNext();
parent2
应该包含所有20项功能。
同时,由于parent1
定义如下:
AbstractParent parent1 = AbstractParent.getParent1Instance();
parent1.populateStringMapInitial();
根据您定义的初始设置, parent1
将有10个项目。
当你这样做时:
parent1 = null;
那里什么都没有。
您的确切查询是什么?