今天由于对方法变量中的final有点困惑,在网上查了一下,才发现在方法变量中,final是这么一回事,这里做一下记录!
什么时候方法参数才需要加final关键字?
- 匿名/局部内部类访问外部方法参数时,外部参数需要加上final关键字。
用代码来解析:
public void start(int interval, final boolean beep) {
/**
* 局部内部类
*/
class TimePrinter implements ActionListener {
public void actionPerformed(ActionEvent event) {
Date now = new Date();
System.out.println("At the tone, the time is " + now);
// 访问外部方法参数beep beep前需加final关键字
if (beep)
Toolkit.getDefaultToolkit().beep();
}
}
ActionListener listener = new TimePrinter();
Timer t = new Timer(interval, listener);
t.start();
}
看看反编译代码:
class TalkingClock$1TimePrinter {
TalkingClock$1TimePrinter(TalkingClock, boolean);
public void actionPerformed(java.awt.event.ActionEvent);
final boolean val$beep;
final TalkingClock this$0;
}
反编译的结果表明:
- 外部方法参数beep成了局部内部类TimePrinter的成员变量val$beep,而且修饰类型也是final
而且
- 局部内部类TimePrinter的成员变量val$beep的值是外部方法参数beep的拷贝,并非外部方法参数beep本身
为什么要final呢?
如果我们在局部内部类中对访问的这个局部变量进行了修改,例如在上面的actionPerformed方法中,而且beep不是final类型,添加了这样的一行代码:
public void actionPerformed(ActionEvent event) {
beep = false;
Date now = new Date();
System.out.println("At the tone, the time is " + now);
if (beep) Toolkit.getDefaultToolkit().beep();
}
这样的话就会出现矛盾,在actionPerformed中将beep置为false,这个beep本质上是我们前面提到的var$beep,而不是外部方法参数beep,那么接下来的代码中,到底以谁为准,就会造成不一致,就会给程序员带来困扰,那么这个时候规定,此时只能使用这个局部变量,而不允许修改它,因此,外部方法参数必须声明为final,而且内部类中的这份拷贝,这个成员变量也是final的。
有意思!!