内部类学习(三)--局部内部类(Local Inner Classes)

这里我们介绍一种特殊的内部类:局部内部类(Local Inner Classes)

在前面的例子中,我们可以发现TimerPrinter仅在start方法中创建一个新的对象时出现过一次,其它地方都没再用到过,这个情况下我们可以把TimerPrinter就定义在start方法中,如下面代码所示:

public void start(){

              class TimerPrinter implements ActionListener{

                     //private boolean beep;

                     public void actionPerformed(ActionEvent e){

                            System.out.println("Bigface,would you be my boy?");

                            if(beep) Toolkit.getDefaultToolkit().beep();

                     }

              }

              TimerPrinter action=new TimerPrinter();

              Timer t=new Timer(interval,action);

              t.start();

       }

注意,局部内部类不需要任何access modifier,否则编译出错,它的作用域一般都被限制在它所在的block中。此时,编译会产生一个名字叫Court$1TimerPrinterclass文件。局部内部类有如下两个优点:

1.  它对外面的所有类来说都是隐藏的,即时是它所属的外部类,仅有它所在的方法知道它;

2.  它不仅可以访问它所属外部类中的数据,还可以访问局部变量,不过局部变量必须生命为final类型,看下面的例子:

package cn.edu.hust.cm.test;

 

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;

import java.awt.Toolkit;

 

import javax.swing.JOptionPane;

import javax.swing.Timer;

public class InnerClassTest {

       public InnerClassTest() {

              super();

       }

       public static void main(String[] args) {

        Court court=new Court();

        court.start(5000,true);

        JOptionPane.showMessageDialog(null,"停止么,CMTobby?");

       }

}

 

class Court{

       public void start(int interval,final boolean beep){

              class TimerPrinter implements ActionListener{

                     public void actionPerformed(ActionEvent e){

                            System.out.println("Cindyelf,are you crazy?");

                            if(beep) Toolkit.getDefaultToolkit().beep();

                     }

              }

              TimerPrinter action=new TimerPrinter();//编译器会自动更改

              Timer t=new Timer(interval,action);

              t.start();

       }

}

注意,局部内部类所要访问的局部变量必须声明为final类型,如上例中红色粗体部分。那么局部内部类是如何访问这个局部变量的呢?我们再对Court$1TimerPrinter反射一下,会得到如下的输出:

class cn.edu.hust.cm.test.Court$1TimerPrinter

{

cn.edu.hust.cm.test.Court$1TimerPrinter(cn.edu.hust.cm.test.Court, boolean);

public  void  actionPerformed(java.awt.event.ActionEvent);

final  cn.edu.hust.cm.test.Court  this$0;

private final  boolean  val$beep;

}

编译器又给我们增加了一个域val$beep,同时构造方法增加了一个boolean类型的参数,因此我们猜想如下的实现过程:

TimerPrinter action=new TimerPrinter(this,beep);//编译器自动增加

然后构造方法中会有:val$beep=beep;这样就成功的把局部变量的值复制过来了。局部变量必须为final就是为了保证成功的复制值,因为final类型的变量一经赋值就不能再发生变化了。

               

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值