java匿名内部类

来源:互联网 发布:舞梦成真软件 编辑:程序博客网 时间:2024/05/01 19:58

今天在看Android的时候突然发觉一个问题,为什么添加一个监听器时代码可以这样写?

 Button btn1;    btn1=(Button)findViewById(R.id.count);    btn1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub}});

才疏学浅,查了书才知道,JAVA中有一个叫匿名内部类的概念。

1、匿名内部类的语法可以这样记忆(仅供记忆):前半部分看起来像是在创建一个对象-------->new  View.OnClickListener()。

                                                            后半部分看起来却像是:一个类的定义。

现在把前后部分合起来解释一下匿名内部类的含义:创建一个实现了View.OnClickListener接口的类的对象,类的定义在后半部分定义了。要注意当View.OnClickListener处替换为一个类时,它表示创建的是一个继承了该类的匿名内部类对象。

2、因为匿名内部类没有构造器(这很好理解:因为它连类名都没有),所以一些初始化操作只能交给参数来完成了。但其中还有一些特殊的地方,在下面的代码①中有体现:

public class Parcel9 {  public Destination destination(final String dest) {    return new Destination() {      private String label = dest;//!!!      public String readLabel() { return label; }    };  }  public static void main(String[] args) {    Parcel9 p = new Parcel9();    Destination d = p.destination("Tasmania");  }}
编译时要求destinatinon()方法中的参数必须为final类型,表面的原因是这个参数dest在匿名内部类中被使用。

在看一段代码②:

abstract class Base {  public Base(int i) {  }  public abstract void f();}public class AnonymousConstructor {  public static Base getBase(int i) {//!!!!!!    return new Base(i) {      { }      public void f() {             }    };  }  public static void main(String[] args) {    Base base = getBase(47);    base.f();  }} 

此段代码中getBAse()的参数却没有使用final修饰,直接原因是参数i并不是直接被匿名内部类使用,而是通过构造器传入的。

上述对为什么使用final修饰参数(还包括局部变量)的问题没有说明原因,在查阅了相关资料后,大家可以参见:匿名内部类使用final参数的问题

我给出的总结是:

①由于方法和方法内创建的匿名内部类生命周期不同,在方法结束后(参数销毁),其中的内部类对象可能还存在。这样就带来了一个问题:对于内部类中对参数的引用失去了意义,它指向的是一个不存在的变量。

②要解决这个问题只有将参数设置为final类型,这样在内部类中操作传入的参数是,它实际上是对参数的一个“复制品”在做操作。而final保证了它们两者的一致。

③对于数据类型和引用类型的参数,使用final的意义是差不多的。

3、匿名类内部是不能创建静态方法与静态域的。

4、匿名类无法做到拓展接口或者实现一个类。




原创粉丝点击