7

Java中的final变量是什么?例如:如果我写final int temp;在函数中,final关键字的含义是什么?
另外,我什么时候想使用 final 变量(作为类变量和函数变量)?
为什么必须将同步块中的变量声明为 final?

4

3 回答 3

16

最终变量和同步代码块确实有一些共同点......如果您声明非最终变量a然后写入synchronized (a) { System.out.println('xxx'); },您将收到警告“非最终字段同步” - 至少在 NetBeans 中。

为什么你不应该在非最终字段上同步?因为如果字段值可能发生变化,那么不同的线程可能会在不同的对象(字段的不同值)上进行同步——所以可能根本没有同步(每个线程可能同时进入同步块)。

在这里查看由于在非最终字段上同步而导致的现实问题的示例:http: //forums.sun.com/thread.jspa?threadID=5379204

于 2010-01-20T13:17:44.450 回答
14

基本上它只是意味着你不能改变价值。对于实例变量,您必须在构造函数中(或使用变量初始化器)一次(且仅一次)分配任何最终变量。同步是一个非常正交的概念。

将局部变量设为 final的主要原因是您可以在匿名内部类中使用它……这与处于同步块中无关。

不可否认,最终变量对于不可变类很有用 - 并且不可变性使多线程环境中的生活更轻松 - 但这是我能想到的两者之间的唯一关系......

编辑:Wildwezyr 的评论在不改变您正在同步的变量方面是有意义的。鉴于他给出的原因,那将是危险的。这就是您所说的“同步块中的变量”吗?

于 2010-01-20T12:38:01.557 回答
4

除了 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 的优势,即使不是绝对需要让您的软件运行,也在于语义上。它使您可以向编译器和处理该代码的下一个人说此变量不应更改,并且尝试更改它可能会导致错误。

于 2010-01-20T13:08:55.870 回答