前言
自己昨天挖的坑含泪都要填完,其实昨天自认为内部类讲的还不够透彻,因为只是说并没有拿出任何证据说明内部类持有了外部类的引用,还有私有变量是怎么获取的,这得怪我本身能力不够,javap的反编译信息看不懂,周末抽空让我把底层的大坑都补上吧。
正文
今天我们来讲局部内部类,匿名内部类和静态内部类。局部内部类声明在方法体内它能看得见外面却不能被方法体外面的东西看见,而且他的修饰符不能为public和private因为它只针对方法可见。最重要的一点就是它引用局部变量必须为final看例子(昨天的例子)
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import javax.swing.Timer;
public class TestInnerClass2 {
public static void main(String[] args) {
TimerClock2 clock = new TimerClock2(true);
clock.start(false);
}
}
class TimerClock2 {
private boolean isClocked = false;
public TimerClock2(boolean isClocked) {
this.isClocked = isClocked;
}
public void start(final boolean isClocked) {
class TimerPrinter implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (!isClocked) {
Date date = new Date();
System.out.println(date);
} else {
Toolkit.getDefaultToolkit().beep();// 会发出铃声
}
}
}
ActionListener listener = new TimerPrinter();
Timer t = new Timer(1000, listener);// 定时器
t.start();
}
}
为什么要声明为final因为start方法结束后isClocked是不存在的,那么声明final变量就是为了拷贝一份到内部类自身的域里面,这样就解决两者声明周期不一致的问题。
匿名内部类so easy就是在父类或者接口扩展其功能的具体实现类或者子类,因为其本身是没有类名的所以其没有构造函数,而交给父类构造器解决(接口就没构造参数这一说法了)
public void start(final boolean isClocked) {
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!isClocked) {
Date date = new Date();
System.out.println(date);
} else {
Toolkit.getDefaultToolkit().beep();// 会发出铃声
}
}
};
Timer t = new Timer(1000, listener);// 定时器
t.start();
}
当然这玩意淫荡的地方不在这,有种我根本没见过的方式
new ArrayList() {{add(1);add(2);add(3);}};
它运用了匿名内部类和实例初始化域(在构造器super()之后调用)
最后静态内部类用的不多,它就是独立于外部类,却又只被外部类使用,而并不是依赖外部类new出的对象具体就是直接Outer.Inner inner = new Outer.Inner ()。(不过我还没想好内部类的使用场景,这个坑估计是要等工作填了)