java 的匿名内部类可以访问所在类的私有属性以及方法的final 声明的值,如下代码:
public interface NoName{ public void say(); //这是一个接口方法 } Public Class Test{ private Stri+ng text1; public Test(){ final int testNum=3; new NoName(){ public void say(){ System.out.println(text1); //在这里可以访问text1值 System.out.println(testNum); //在这里可以访问testnum的值 //testNum=4;error我们不能改变final的值 } }; } public void setText1(String text){ this.text1=text; } public String getText1(){ return this.text1; } 我们不仅思考,为什么我们在访问方法的局部变量的时候,要声明成为final的值呢? 我们现在声明一个Person的类 public class Person{ private String name; public void setName(String name){ this.name=name; } public String getName(){ return this.name; } } 然后,我们在匿名类里面重载say方法 final Person p1=new Person; new NoName(){ public say(){ p1.setName("corey"); p1=new Person();//error } }; 在这里我们能够改变p1的值; 这是因为匿名类会将final属性作为一个模板拷贝到自己的实例内存区中作为一个属性字段 如:p1----> |--------| | name | | | |--------| 这个时候p1的指向是固定不变的,我们虽然能改变里面的name值,但是p1=new Person();的时候会发生
p1----| |--------| | | name | | | | | |--------| |--> |--------| | name | | | |--------|
这个时候违背了final原则,设计的最初的为了给使用匿名类的人造成歧义
因为我们说了匿名类中的类在访问方法的变量的时候,是将这个final变量拷贝
p1----> |--------| <-----------p'1 | name | | | |--------|
这个时候,我们如果不用final的话
我们可能会作出这样的操作p1=new Person();,我们会把p‘1的内存区当作p1处理(事实上我们认为我们访问和改变的是p1变量)
p1-------->|--------| | name | p'1---| | | | |--------| |--> |--------| | name | | | |--------| 但是事实上p1变量是没有作出修改的,我们利用内部类处理方法中的变量,本身就是为了改变他,而现在我们 在改变另外一个内存区里面的数据,而目标区域没有得到改变! 这也是为什么sun在设计的时候要规定必须声明为final