考虑以下代码:
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
InnerClass
个实例仍然可以访问OuterClass
引用的字段ocs
怎么样 ?
这与封闭有关吗?即在上下文不再存在之后,将变量保存在上下文中,在本例中为OuterClass
对象。
答案 0 :(得分:2)
InnerClass在创建外部类时会自己引用它。如果对外部类的引用为null,则不涉及内部类维护的引用。见the java language ref
类O的直接内部类C的实例i与O的实例相关联,称为i的直接封闭实例。在创建对象时确定对象的直接封闭实例(如果有)(第15.9.2节)。
答案 1 :(得分:2)
您要更新的只是对实例的引用,而不是实例本身。引用只是指向别的东西。
将其想象为手机中的通讯录 - 您正在存储您的朋友'电话号码,以便您可以拨打他们的电话;从联系人中删除他们的号码并不会使他们的手机消失。
答案 2 :(得分: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
)