Java中的final变量是什么?例如:如果我写final int temp;
在函数中,final关键字的含义是什么?
另外,我什么时候想使用 final 变量(作为类变量和函数变量)?
为什么必须将同步块中的变量声明为 final?
3 回答
最终变量和同步代码块确实有一些共同点......如果您声明非最终变量a
然后写入synchronized (a) { System.out.println('xxx'); }
,您将收到警告“非最终字段同步” - 至少在 NetBeans 中。
为什么你不应该在非最终字段上同步?因为如果字段值可能发生变化,那么不同的线程可能会在不同的对象(字段的不同值)上进行同步——所以可能根本没有同步(每个线程可能同时进入同步块)。
在这里查看由于在非最终字段上同步而导致的现实问题的示例:http: //forums.sun.com/thread.jspa?threadID=5379204
基本上它只是意味着你不能改变价值。对于实例变量,您必须在构造函数中(或使用变量初始化器)一次(且仅一次)分配任何最终变量。同步是一个非常正交的概念。
将局部变量设为 final的主要原因是您可以在匿名内部类中使用它……这与处于同步块中无关。
不可否认,最终变量对于不可变类很有用 - 并且不可变性使多线程环境中的生活更轻松 - 但这是我能想到的两者之间的唯一关系......
编辑:Wildwezyr 的评论在不改变您正在同步的变量方面是有意义的。鉴于他给出的原因,那将是危险的。这就是您所说的“同步块中的变量”吗?
除了 Jon Skeet 所说的,值不能改变,但内容可能会改变。
final Integer one = new Integer(1);
...
one = new Integer(2); // compile error
final List list = new ArrayList();
...
list = new ArrayList(); // compile error
list.add(1); // Changes list, but that's fine!
还要注意 final 和 static final 是不一样的。final 在实例的范围内,而 static final 对于类的所有实例都是相同的(在其他语言中,这可以称为常量)。
就我个人而言,我认为 final 的优势,即使不是绝对需要让您的软件运行,也在于语义上。它使您可以向编译器和处理该代码的下一个人说此变量不应更改,并且尝试更改它可能会导致错误。