public classtest01 {
public static void main(String[] args) {
test01 test01= new test01();
final String name = "小武";
class man implements Man{
@Override
public String output() {
return "我的名字叫:" + name;
}
}
System.out.println(newman().output());
}
}
interface Man {
String output();
}
public classtest01 {
public static void main(String[] args) {
test01 test01= new test01();
final String name = "小武";
class man implements Man{
@Override
public String output() {
return "我的名字叫:" + name;
}
}
System.out.println(newman().output());
}
}
上面程序里的普通内部类访问了name局部变量,那么该变量也应该使用final修饰。
Java要求所有被内部类访问的局部变量都是用final修饰也是有原因的:对于普通局部变量而言,它的作用域就是停留在该方法内,当方法执行结束,该局部变量也随之消失;但内部类则可能产生隐式的“闭包(Closure)”,闭包将使得局部变量脱离它所在的方法继续存在。下面看一个例子:
[java]
public class test01{
public static void main(String[] args) {
final String name = "小武灵灵";
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i< 100; i++) {
System.out.println(name+ i + "岁了");
try {
Thread.sleep(100);
} catch(Exception e) {}
}
}
}).start();
}
}
public class test01{
public static void main(String[] args) {
final String name = "小武灵灵";
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i< 100; i++) {
System.out.println(name+ i + "岁了");
try {
Thread.sleep(100);
} catch(Exception e) {}
}
}
}).start();
}
}
正常情况下,当程序执行完start()之后,main方法的生命周期就结束了,局部变量name的作用域也会随之结束。但实际上上个程序中只要新线程里的run方法没有执行完,匿名内部类的实例的生命周期就没有结束,将一直可以访问name局部变量的值,这就是内部类会夸大局部变来那个作用域的实例。
由于内部类可能扩大局部变量的作用域,如果再加上这个被内部类访问的局部变量没有final修饰,也就是说该变量的值可以随意改变,那么将引起极大的混乱,因此Java编译器要求所有被内部类访问的局部变量必须使用final修饰符修饰。