2015-02-04 1 views
-1

Рассмотрим следующий фрагмент кода:Установка экземпляра внешнего класса в null, и все же внутренние экземпляры класса могут обращаться к внешнему классу. Как?

class OuterClass{ 
    String ocs="ocs"; 
    class InnerClass{ 
     String ics="ics"; 
     void innerMeth(){ 
      System.out.println(ocs); 
     } 
    } 
} 
//main class 
public class HelloWorld{ 
    public static void main(String []args){ 
     OuterClass ob=new OuterClass(); 
     OuterClass.InnerClass ob1=ob.new InnerClass(); 
     ob=null; 
     ob1.innerMeth(); 
    } 
} 

Все еще печатает строку 'OCS'.
в основном даже если я установлен OuterClass экземпляр для null.
экземпляр все еще может обращаться к OuterClass справка поле ocs
Как?

Это как-то связано с закрытием? поддерживая переменные в контексте даже после того, как контекст больше не является, в данном случае объектом OuterClass.

+4

Экземпляр не может быть пустым. Это не концепция, которая существует. Переменная может хранить значение «null». Это не влияет на другую ссылку на объект. –

ответ

1

Добавление метода finalize() к каждому классу даст лучшее понимание.

class OuterClass { 
    protected void finalize() throws Throwable { 
     System.out.println("oc instance finalized.."); 
    }; 
    String ocs = "ocs"; 

class InnerClass { 
    String ics = "ics"; 

    protected void finalize() throws Throwable { 
     System.out.println("IC instance finalized"); 
    }; 

    void innerMeth() { 
     System.out.println(ocs); 
    } 
} 

}

// main class 
class HelloWorld { 
    public static void main(String[] args) { 
     OuterClass ob = new OuterClass(); 
     OuterClass.InnerClass ob1 = ob.new InnerClass(); 
     ob = null; 
     // ob1=null; 
     System.gc(); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     ob1.innerMeth(); // you will get NPE here 
    } 
} 

Когда только ob установлен в null, ob1 все еще имеет ссылку на него, так что он не будет завершена, и, следовательно, по-прежнему доступны.

Если вы установите ob, а также ob1 к null, то выход будет:

IC instance finalized 
oc instance finalized.. 
Exception in thread "main" java.lang.NullPointerException 
    at HelloWorld.main 

, потому что не будет никаких ссылок на любой ob или ob1 поэтому оба объекта finalized. Обратите внимание, что это ссылка, которая имеет значение null. Другие ссылки могут по-прежнему указывать на объект вместе с ob (в вашем случае ob1)

+0

У всех нас будет такой момент порой :) – TheLostMind

2

InnerClass со своей собственной ссылкой на внешний класс, когда он создан. Если вы удалите ссылку на внешний класс, это не касается ссылки, которую поддерживает внутренний класс. См the java language ref

экземпляра я прямой внутреннего класс С классом O связан с экземпляром O, известным как непосредственно вмещающим экземпляр I. При создании объекта немедленно определяется экземпляр объекта, если он есть, (§15.9.2).

2

Все, что вы обновляете, является ссылкой на экземпляр, а не на сам экземпляр. Ссылка - это просто вещь, которая указывает на что-то другое.

Думайте об этом как о контактах в телефоне - вы храните телефонные номера своих друзей, чтобы вы могли позвонить их телефону; удаление их номера из ваших контактов не приводит к исчезновению их телефона.

+0

Ну да, важно запомнить «ссылочную переменную» == 'instance' себя! – Sarabjeet

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