java中的最终变量和同步块

时间:2010-01-20 12:35:08

标签: java variables final synchronized

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

3 个答案:

答案 0 :(得分:14)

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

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

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

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

答案 1 :(得分:14)

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

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

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

答案 2 :(得分: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的优势,即使并非绝对需要让你的软件正常工作,也具有语义含义。它为您提供了向编译器以及处理该代码的下一个人说明该变量无意更改的可能性,并且尝试更改它可能会导致错误。