0

我无法理解我遇到的一段代码。

以下是一段类似的代码:

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 是 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 个元素。谁能解释这背后的原因?我想我在这里遗漏了一些非常基本的东西。

4

2 回答 2

1

我想我在这里遗漏了一些非常基本的东西。

很基础的东西。静态变量,或者说,类级变量在类的所有实例之间共享。所以你只有一个类级变量的实例:

private static AbstractParent parent1;  

并且每个请求都AbstractParent.getParent1Instance()返回那个并且总是相同的实例。

您在 main 中的方法级声明:

AbstractParent parent1

不会改变任何东西,因为它在完全方法本地和完全不同的类中,AbstractAndStaticTest,所以 parent1 = null 只使 AbstractParent 实例符合垃圾收集的条件,而不是类对象和类级别的实例,因为它们永远不符合 GC 的条件。

于 2013-07-10T12:16:12.520 回答
0

由于您的代码运行:

    AbstractParent parent2 = AbstractParent.getParent1Instance();  
    parent2.populateStringMapNext();  

parent2应该有所有 20 个项目作为你的功能。

同时,sinceparent1定义如下:

AbstractParent parent1 = AbstractParent.getParent1Instance();  
parent1.populateStringMapInitial();  

parent1根据您定义的初始设置,将有 10 个项目。

当你这样做时:

parent1 = null;

那里什么都没有。

您在这里的确切查询是什么?

于 2013-07-10T12:16:37.787 回答