Java内部类



 一、为何使用内部类

  • 内部类可以访问外部类中的所有数据,包括声明为private的数据。
  • GUI中的回调方法callback时,可以让组件共享一个对象,其中包含当指定事件触发时执行的操作代码,这个对象可以实现一个事件处理接口或继承一个抽象适配器类。
  • 对包中的其他类实现隐藏。
  • 匿名内部类有组与单一组件的事件处理代码的简化。


二、内部类的特殊语法

public class TalkClock {

	private int interval;
	private boolean beep;

	public TalkClock(int interval, boolean beep) {
		this.interval = interval;
		this.beep = beep;
	}
	
	public void start() {
		ActionListener listener = new TimerPrinter();
		Timer t = new Timer(interval, listener);
		t.start();
	}
	
	public class TimerPrinter implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			Date date = new Date();
			System.out.println("the time is: "+date);
			if(beep)
				Toolkit.getDefaultToolkit().beep();
		}
	}
	
	public static void main(String[] args) {
		TalkClock c = new TalkClock(10000, true);
		c.start();
		JOptionPane.showMessageDialog(null, "wow");
		System.exit(0);
	}
}

 
  编译之后会发现生成两个类,TalkClock$TimerPrinter.class和TalkClock.class。使用JD-GUI打开class文件:其中TalkClock$TimerPrinter.class文件如下

public class TalkClock$TimerPrinter implements ActionListener {
	public void actionPerformed(ActionEvent paramActionEvent) {
		Date localDate = new Date();
		System.out.println("the time is: " + localDate);
		if (TalkClock.access$000(this.this$0))
			Toolkit.getDefaultToolkit().beep();
	}
}

 
  TalkClock.class文件如下 

public class TalkClock {
	private int interval;
	private boolean beep;
	
	public TalkClock(int paramInt, boolean paramBoolean) {
		this.interval = paramInt;
		this.beep = paramBoolean;
	}

	public void start() {
		TalkClock.TimerPrinter localTimerPrinter = new TalkClock.TimerPrinter();
		Timer localTimer = new Timer(this.interval, localTimerPrinter);
		localTimer.start();
	}

	public static void main(String[] paramArrayOfString) {
		TalkClock localTalkClock = new TalkClock(10000, true);
		localTalkClock.start();
		JOptionPane.showMessageDialog(null, "wow");
		System.exit(0);
	}

	public class TimerPrinter implements ActionListener {
		public void actionPerformed(ActionEvent paramActionEvent) {
			Date localDate = new Date();
			System.out.println("the time is: " + localDate);
			if (TalkClock.this.beep)
				Toolkit.getDefaultToolkit().beep();
		}
	}
}

 
   可以看到外部类可以通过

  TalkClock.TimerPrinter localTimerPrinter = new TalkClock.TimerPrinter();

  也就是:outerClass.innerClass的形式访问内部类。同时内部类也可以通过TalkClock.this.beep,也就是形如outerClass.this.field的形式访问外部类的参数。

  接下来,我们使用命令行:

  javap -private TalkClock$TimerPrinter

  结果如下:

  我们,会发现使用命令行会多出一个由编译器编译指定的一个this$0参数。回顾一下TalkClock$TimerPrinter.class文件中出现的TalkClock.access$000(this.this$0)代码。再次对TalkClock文件使用上述命令,来看看是不是有变化呢

  javap -private TalkClock


  不出所料,javap为我们提供了一个不可见的access$000方法,这是否存在某些安全隐患呢,事实上,这需要对类文件有这深入的了解才可能做到。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值