hi 遇到一个问题,请看下面代码
int i = 0;
while (i < 50) {
final String xx = "xx" + i;
System.out.println(Thread.currentThread().getName() + " " + xx);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + xx);
}
});
t.start();
i++;
}
thread里面的xx是怎么区分到底是哪个final xx呢?
------解决思路----------------------
这个主要跟匿名内部类的实现原理有关, 我也不懂, 但你可以按照下面的代码来理解.
public static void main(String[] args) {
int i = 0;
while (i < 50) {
final String xx = "xx" + i;
Thread t = new Thread(new R(xx));
t.start();
i++;
}
}
static class R implements Runnable {
String xx;
public R(String xx) {
this.xx = xx;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + xx);
}
}
也就是说 R 对象内部已经记录了当前while 块内xx的引用, run的时候打印的就是那个时刻的xx值.
------解决思路----------------------
java是这样实现匿名内部类(AIC)对局部变量的引用的:
AIC会定义一个private成员,用来存放要引用的局部变量的拷贝。也就是说,AIC使用的不是局部变量本身而是其拷贝。如果这时候局部变量是non final的,那么该局部变量或者AIC内的拷贝更改时,会引起数据同步的问题,因此为了避免这种情况,JAVA强制AIC只能引用final变量。
这段话同样解释了题主的疑惑。