2

我的问题是为什么我应该使用 final 来装饰变量 list?它由匿名内部类的实例使用,如果没有 final,它将无法编译。

代码如下所示:

public class TwoThreadsOneListCurrModi
{
  public static void main(String[] args)
  {    
     final List<String> list = Collections.synchronizedList(new ArrayList<String>());

    for (int i =0 ; i<20;i++)
      list.add(String.valueOf(i));
    Thread t1 = new Thread(new Runnable(){

      @Override
      public void run()
      {
          synchronize(list) {
          System.out.println("size of list:" +list.size());
          }
      }
    });

    t1.start();  
  }
}

但是,如果我使用普通课程,那很好。

public class TwoThreadsOneListCurrModi2

{
  public static void main(String[] args)
  {    
     final List<String> list = Collections.synchronizedList(new ArrayList<String>());
    initialize list;

    Thread t1 = new WorkThread(list);
    Thread t2 = new WorkThread(list);    
    t1.start();  
    t2.start();
  }
}
class WorkThread extends Thread{
    List<String> list;
    public void run(){
       do sth with list and synchronize block on list
  }
  Work1(List<String> list)
  {    this.list = list;  }
}
4

1 回答 1

11

这与多线程无关。它在那里是因为您试图list从匿名内部类的方法访问。在这种情况下,Java 将始终签署错误。

Runnable在您的情况下,您正在使用new关键字创建此处的匿名实例。您尝试取消引用的所有内容都run需要是final.

如果您对 final 关键字的必要性感到好奇,您可以查看 Jon Skeet 的详尽答案,该答案对其进行了深入解释。

关键是,当您创建匿名内部类的实例时,该类中使用的任何变量都会通过自动生成的构造函数复制其值,如果该变量可以被方法的其余部分修改并且看起来很奇怪反之亦然。

于 2013-07-21T20:53:22.890 回答