静态对象中非静态变量的范围

时间:2013-07-10 12:03:28

标签: java static abstract

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

以下是一段类似的代码:

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个元素。任何人都可以解释这背后的原因吗?我想我错过了一些非常基本的东西。

2 个答案:

答案 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;
那里什么都没有。

您的确切查询是什么?