内部类是一个非常重要的概念,了解内部类对lambda表达式的学习很有帮助
Java内部类
定义:Java内部类是定义在另一个类中的类
内部类可以访问该类所在的作用域中的数据,包括私有数据。
内部类可以对同一包中的其他类隐藏起来。
当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
使用内部类访问对象状态
此处定义了一个TimerClock类。构造此类需提供interval,beep两参数public class TalkingClock { private int interval private boolean beep public TalkingClock(int interval, boolean beep){...} public void start(){...} public class TimePrinter implements ActionListener // an inner class { ... } }
需要注意的是,这里TimePrinter类位于TalkingClock类内部,此处定义TimePrinter类。
public class TimePrinter implements ActionListener{ public void actionPerformed(ActionEvent event){ System.out.print(new Date()); if(beep) Toolkit.getDefaultToolkit().beep(); } }
可以看到神奇的事发生了,TimePrinter没有实例域或名为beep的变量,但却引用了TalkingClock的域。内部类既可以访问自身的域,也可以访问创建他的外围对象的域。
内部类的语法规则
可以像这样编写在外部类中的内部类的构造器:
outerObject.new InnerClass(Construction parameter)
例如
ActionListener listener = this.new TimerPrinter //多态声明
this指代构造timePrinter对象的外围类。同时,也可在外部类外调用内部类。此处当timePrinter是一个公有内部类时,可以将外围类的引用设置为其他对象比如
TalkingClock jabberer = new TalkingClock(1000,true); TalkingClock.TimerPrinter listener = jabberer.new TimerPrinter(); TalkingClock.TimePrinter listener = new TalkingClock(1000,true).new TimerPrinter();//等价写法
需要注意的是,内部类中所有声明的静态域都为final。内部类中不能有static方法。
局部内部类
局部类通常被定义在方法中。
public void start() { public void actionPerformed(Action event) { System.out.println(new Date()); if(beep) Toolkit.getDefaultToolkit().beep(); } ActionListener listener = new TimePrinter(); Time t = new Timer(interval, listener); t.start(); }
局部类不能用public或public访问说明符进行声明,它的作用被限定在这个局部类的块中。局部类有一个优势,即对外部世界完全隐藏,即使外部类的其他代码也不能访问他,除start方法外,没有任何方法知道他的存在。
由外部类访问变量
局部内部类若想访问所在方法的局部变量,该变量必须为有效final。原因有是因为,new出来的对象在堆内存中,局部变量由方法创建,在栈内存中,方法结束后自动清出。所以要使用final进行拷贝。
匿名内部类
将局部内部类的使用在深入,假如只创建这个类的一个对象,就不必命名了。
public void start(int interval, boolean beep){ ActionListener listener = new ActionListener(){ public void actionPerformed(ActionEvent event) { System.out.println(new Date()); } }; Timer t = new TImer(interval,listener); t.start(); }