当前位置: 代码迷 >> J2SE >> final 内部变量的一个有关问题
  详细解决方案

final 内部变量的一个有关问题

热度:74   发布时间:2016-04-23 20:01:48.0
final 内部变量的一个问题
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变量。

这段话同样解释了题主的疑惑。
  相关解决方案