@gnudennis
2015-04-26T15:28:38.000000Z
字数 4269
阅读 2524
CoreJava
- 为何使用内部类
- 访问外围类数据
- 内部类的语法规则
- 局部内部类
- 匿名内部类
内部类(inner class)是定义在另一个类中的类。
示例:
package corejava.inner;import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.Date;/*** Created by guolong.fan on 15/4/26.*/public class InnerClassTest {public static void main(String[] args) {TalkingClock clock = new TalkingClock(1000, true);clock.start();JOptionPane.showMessageDialog(null, "Quit program?");System.exit(0);}}class TalkingClock {public TalkingClock(int interval, boolean beep) {this.interval = interval;this.beep = beep;}public void start() {ActionListener listener = new TimePrinter();Timer timer = new Timer(interval, listener);timer.start();}private int interval;private boolean beep;public class TimePrinter implements ActionListener {@Overridepublic void actionPerformed(ActionEvent actionEvent) {System.out.println("At the tone, the time is " + new Date());if (beep) Toolkit.getDefaultToolkit().beep();}}}
if (beep)... 访问了外围类的私有属性.
内部类是一种编译器现象,与虚拟机无关. 使用 javap 分析编译器如何生成代码的?
javap -private TalkingClock$TimePrinter.class
- 内部类的命名. outclass$innerclass(eg.
TalkingClock$TimePrinter)- 内部类生成外部类实例的引用(final)+构造器.
public class corejava.inner.TalkingClock$TimePrinter extends java.lang.Object implements java.awt.event.ActionListener{final corejava.inner.TalkingClock this$0;public corejava.inner.TalkingClock$TimePrinter(corejava.inner.TalkingClock);public void actionPerformed(java.awt.event.ActionEvent);}<div class="md-section-divider"></div>
- 针对内部类访问了的private fields, 外围类生成 access$ 代码(package权限的getter).
class corejava.inner.TalkingClock extends java.lang.Object{private int interval;private boolean beep;public corejava.inner.TalkingClock(int, boolean);public void start();static boolean access$000(corejava.inner.TalkingClock);}<div class="md-section-divider"></div>
最终,编译器生成如下代码.
class TalkingClock {public TalkingClock(int interval, boolean beep) {this.interval = interval;this.beep = beep;}public void start() {ActionListener listener = new TimePrinter(this);Timer timer = new Timer(interval, listener);timer.start();}static boolean access$000(corejava.inner.TalkingClock);private int interval;private boolean beep;public class TimePrinter implements ActionListener {public TimePrinter(TalkingClock clock) {outer = clock;}@Overridepublic void actionPerformed(ActionEvent actionEvent) {System.out.println("At the tone, the time is " + new Date());if (access$000()) Toolkit.getDefaultToolkit().beep();}...private TalkingClock outer;}}<div class="md-section-divider"></div>
OuterClass.this. beep可以写成TalkingClock.this.beep.outObject.new InnerClass(construction parameters).
内部类:ActionListener listener = this.new TimePrinter();其他程序中:TalkingClock jabberer = new TalkingClock(1000, true);TalkingClock.TimePrinter listener = jabberer.new TimePrinter();<div class="md-section-divider"></div>
直接定义在方法中.
public class InnerClassTest {public static void main(String[] args) {TalkingClock clock = new TalkingClock(1000, true);clock.start();JOptionPane.showMessageDialog(null, "Quit program?");System.exit(0);}}class TalkingClock {public TalkingClock(int interval, boolean beep) {this.interval = interval;this.beep = beep;}public void start() {public class TimePrinter implements ActionListener {@Overridepublic void actionPerformed(ActionEvent actionEvent) {System.out.println("At the tone, the time is " + new Date());if (beep) Toolkit.getDefaultToolkit().beep();}}ActionListener listener = new TimePrinter();Timer timer = new Timer(interval, listener);timer.start();}private int interval;private boolean beep;}<div class="md-section-divider"></div>
package corejava.inner;import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.Date;/*** Created by guolong.fan on 15/4/26.*/public class InnerClassTest {public static void main(String[] args) {TalkingClock clock = new TalkingClock(1000, true);clock.start();JOptionPane.showMessageDialog(null, "Quit program?");System.exit(0);}}class TalkingClock {public TalkingClock(int interval, boolean beep) {this.interval = interval;this.beep = beep;}public void start() {ActionListener listener = new ActionListener() {@Overridepublic void actionPerformed(ActionEvent actionEvent) {System.out.println("At the tone, the time is " + new Date());if (beep) Toolkit.getDefaultToolkit().beep();}};Timer timer = new Timer(interval, listener);timer.start();}private int interval;private boolean beep;}