匿名内部类与final关键字
1. 了解匿名内部类
匿名内部类是一种特殊的内部类,它没有指定类名,直接在定义时实现接口或继承一个类并覆写其方法。通常情况下,我们使用匿名内部类来简化代码,避免创建过多的类文件。例如:
```
Button button = new Button();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// ...
}
});
```
上面的代码中,我们使用匿名内部类实现了ActionListener接口,并将其作为参数传入Button的addActionListener方法中。
2. 匿名内部类只能访问final的变量
在使用匿名内部类时,我们需要注意到一个重要的限制:只能访问final的变量。例如:
```
int i = 0;
Button button = new Button();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(i); // 编译错误:Cannot refer to a non-final variable i inside an inner class defined in a different method
}
});
```
上面的代码中,我们在匿名内部类中尝试访问外部变量i,但是会得到一个编译错误。这是因为匿名内部类中使用的变量必须是final的,或者实质上相当于final的变量(即一旦赋值后,不能再改变其值)。
3. final变量与闭包
虽然我们不能在匿名内部类中修改final变量的值,但是我们可以使用final变量来实现一种称为“闭包”的技术。例如:
```
Button button = new Button();
for (int i = 0; i < 10; i++) {
final int j = i; // 注意这里必须使用final修饰
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(j); // 输出i的值
}
});
}
```
上面的代码中,我们使用final变量j来捕获外部变量i的值,并在匿名内部类中使用。由于j是final的,因此在循环中创建的每个匿名内部类都可以访问对应的j变量,从而实现了闭包的效果。
,在使用匿名内部类时,我们需要注意到它只能访问final的变量。虽然这个限制看起来有些繁琐,但是它可以有效地防止变量不小心被修改,同时也可以帮助我们实现一些高级的技术,如闭包。