2013-07-10 2 views
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 через ребенка? Карта является частной для GrandParent (т. Е. На уровне объекта), а объект AbstractParent является статическим (т.е. на уровне класса). Может ли быть возможностью, чтобы переменная «map» могла иметь право на сбор мусора даже в случае экземпляра AbstractParent (Child)?

Во-вторых, что может быть причиной такого рода дизайна?

Я проверил вышеупомянутый код, чтобы иметь нестатическую ссылку на статический экземпляр 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 элементов. Может ли кто-нибудь объяснить причину этого? Наверное, я пропустил что-то очень основное.

ответ

1

Я предполагаю, что у меня отсутствует что-то очень основное.

Очень простая вещь. Статическая переменная или другая указанная переменная уровня класса распределяется между всеми экземплярами класса. Таким образом, у вас есть только один экземпляр переменной класса уровня:

private static AbstractParent parent1; 

и каждый запрос AbstractParent.getParent1Instance() возвращается, что один и тот же всегда экземпляра.

Ваше объявление метода уровня в основной:

AbstractParent parent1 

ничего не меняет, потому что это в полностью методе локального и в совершенно другом классе, AbstractAndStaticTest, так Parent1 = нуль только делает AbstractParent экземпляр, имеющих право на Garbage Collection , но не класса, а не экземпляров уровня, поскольку они никогда не имеют права на GC.

+0

Мой вопрос в том, какова область действия переменной «map».Поскольку можно видеть, что «Карта» является частной для GrandParent, и мы создаем объект Child, следовательно, карта не должна находиться в области Child. – Adithya

+0

И это не так, что заставляет вас думать по-другому? Вышеупомянутый шаблон является одноточечным. 'static getParent1Instance()' будет только один раз создавать новый экземпляр, последующие запросы возвратят тот же объект. Следовательно, вы получаете 20 элементов. –

0

Так как ваш код будет:

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

parent2 должны иметь все 20 пунктов, как ваша функция идет.

В то же время, так как parent1 определяется следующим образом:

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

parent1 будет иметь 10 пунктов в соответствии с начальной настройки вы определили.

И когда вы делаете:

parent1 = null; 

там ничего нет.

Каков ваш точный запрос здесь?

Смежные вопросы