先上代码
public class Mytest1 {
static List a1 = new ArrayList();
public static void main(String[] args) {
final List a2 = new ArrayList();
Thread b = new Thread() {
@Override
public void run() {
System.out.printf("a1=" + a1);
System.out.printf("a2=" + a2);
}
};
}
}
这段代码是可以编译通过的,a1为类变量,a2为方法变量(局部变量),但是a2变量必须要加final关键字修饰,这是为什么呢?
这和变量的生命周期有关的,main方法执行完成后,局部变量a2将会被回收,a2也就不存在了,而你在匿名内部对象中却还要使用这个变量,显然要定义成final。定义成final的目的是增强变量的生存期,使在匿名内部类对象中使用的时候这个变量还存在。
而类变量a1 不会因为main方法执行结束而被回收,所以a1不用加final修饰。
备注:上例中使用的匿名对象是Thread,其实任何一个匿名对象如果想访问局部变量a2,均需要定义为final变量
public class Mytest1 {
static List a1 = new ArrayList();
public static void main(String[] args) {
final List a2 = new ArrayList();
MyObj obj = new MyObj();
obj.aa(a1);
obj.aa(a2);
new MyObj() {
@Override
void aa(List a) {
super.aa(a);
System.out.printf("a1=" + a1);
System.out.printf("a2=" + a2);
}
};
}
}
class MyObj {
void aa(List a) {
System.out.printf("a=" + a);
}
}
public class Mytest1 {
static List a1 = new ArrayList();
public static void main(String[] args) {
final List a2 = new ArrayList();
Thread b = new Thread() {
@Override
public void run() {
System.out.printf("a1=" + a1);
System.out.printf("a2=" + a2);
}
};
}
}
这段代码是可以编译通过的,a1为类变量,a2为方法变量(局部变量),但是a2变量必须要加final关键字修饰,这是为什么呢?
这和变量的生命周期有关的,main方法执行完成后,局部变量a2将会被回收,a2也就不存在了,而你在匿名内部对象中却还要使用这个变量,显然要定义成final。定义成final的目的是增强变量的生存期,使在匿名内部类对象中使用的时候这个变量还存在。
而类变量a1 不会因为main方法执行结束而被回收,所以a1不用加final修饰。
备注:上例中使用的匿名对象是Thread,其实任何一个匿名对象如果想访问局部变量a2,均需要定义为final变量
public class Mytest1 {
static List a1 = new ArrayList();
public static void main(String[] args) {
final List a2 = new ArrayList();
MyObj obj = new MyObj();
obj.aa(a1);
obj.aa(a2);
new MyObj() {
@Override
void aa(List a) {
super.aa(a);
System.out.printf("a1=" + a1);
System.out.printf("a2=" + a2);
}
};
}
}
class MyObj {
void aa(List a) {
System.out.printf("a=" + a);
}
}