/**
* @param args
*/
public static void main(String[] args){
Test t= new Test();
System.out.println(t.getA().getO());
System.gc();
System.out.println(t.getA().getO());
}
public A getA(){
final Object o = new Object();
return new A(){
@Override
public Object getO() {
return o;
}
};
}
}
interface A{
public Object getO();
}
看上面一段代码。
为何下划线的那段代码要用红色的final呢?
其实大家有没有想过,如果不用final会发生什么事情?首先,这个对象会随时被垃圾回收器收集掉(看起来是这样,呵呵,实际上不是这样),这就失去了稳定性.
其次,这段代码在编译的时候,外部类Test是作为一个指针送入匿名内部类中的,但这对于取得常引用o指向的对象没有意义,因为那个final型引用是方法体内部的局部引用,那这个匿名内部类的类体内部在编译时就无法获得一个局部.
实际上,从java汇编指令可以看出来,实际的操作是在匿名内部类中形成了一个类似私有的final型引用,而那个局部变量的引用将被复制一份存在于匿名内部类中,这个引用指向这个外部类方法中的常引用对象.实际上,java完全可以做到非final型的局部引用被内部类引用,这样就会使代码的可读性变差,或者说是可理解性变差.
假设下面代码能通过编译,
public A[] getAArray(){/* final*/ Object o = new Object(){
public String toString(){return "Obj";}
};//
A a1= new A(){
@Override
public Object getO() {
A a1= new A(){
@Override
public Object getO() {
return o;
}
};
}
};
A a2=new A(){
@Override
public Object getO() {
o=null;
public Object getO() {
o=null;
return o;
}
}
}
A[] as=new A[2]{a1,a2};
return as;
}
as[1].getO();//null
as[0].getO();//"Obj"
但是从字面上理解,as[1].getO();as[0].getO();操作的都是"/* final*/ Object o",但事实上,按照java的实现机制不是操作的同一个引用,这就引起了歧义.
我说的可能有点拗口,大家可以仔细去理解一下这里面的关系.
2 评论 :
your blog is feel good......
thanks.but could you tell what is good?
发表评论