现在的位置: 首页 > 综合 > 正文

有关java匿名内部类的一些思考

2018年03月29日 ⁄ 综合 ⁄ 共 1295字 ⁄ 字号 评论关闭
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
【上篇】
【下篇】

抱歉!评论已关闭.