final
变量声明为final,可以防止修改变量的内容,本质上就是将变量变成了常量。这意味着final变量必须在声明时进行初始化。可以通过两种方式完成这个工作:
- 可以在声明时为其提供一个值
- 可以在构造函数中为其赋值
final变量名全部使用大写,这是一种常见的编码阅读。
除了可以将变量声明为final之外,方法参数和局部变量也可以声明为final。将参数声明为final,可以防止在方法中修改参数。将局部变量声明为final,可以防止多次为其赋值。
关键字final也可以应用于方法,但是含义于应用于变量有本质区别。
1 | class Test |
final在JMM中的处理
final在该对象的构造函数中设置对象的字段,当线程看到该对象时,将始终看到该对象的final字段的正确构造版
本。
伪代码示例:f = new finalDemo();
读取到的 f.x 一定最新, x为final字段如果在构造函数中设置字段后发生读取,则会看到该final字段分配的值,否则它将看到默认值;
伪代码示例:public finalDemo(){ x = 1; y = x; };
y会等于1;读取该共享对象的final成员变量之前,先要读取共享对象。
伪代码示例:r = new ReferenceObj(); k = r.f ;
这两个操作不能重排序通常被static final修饰的字段, 不能被修改 。然而System.in、 System.out、 System.err被static final修饰,却可以修改,遗留问题, 必须允许通过set方法改变,我们将这些字段称为写保护,以区别于普通final字段;
多线程编程
- 希望变量在构造的时候被其他线程正常读取