final用来实现不可变类,方法和变量的申明,即类不可被继承,方法不可被重写,变量不可被重新赋值。final实现了在不需要同步的情况下即可以保证线程安全。但是需要注意的是,需要保证对象的构造函数完成后对final成员变量进行引入,即安全构造。
参考资料:
声明为 final 的字段初始化一次后,在正常情况下它的值不会再改变。final 字段的 详细语义与普通字段稍有不同。尤其是,编译器有很大的自由,能将对 final 字段 的读操作移到同步屏障之外,然后调用任意或未知的方法。同样,也允许编译器将 final 字段的值保存到寄存器,在非 final 字段需要重新加载的那些地方,final 字段 无需重新加载。
final 字段也允许编程人员在不需要同步的情况下实现线程安全的不可变对象。一个 线程安全的不可变对象被所有线程都视为不可变的,即使不可变对象的引用在线程间传递时存在数据争用。这提供了安全保证,可以防止不正确或恶意代码误用了不 可变类。
final 字段必须正确使用才能保证不可变。当对象的构造器执行结束,就认为该对象 是完全初始化了的。一个线程只有在看到某个对象引用之前,该对象就已经完全初 始化了,才能保证这个线程能看到该对象正确初始化的 final 字段值。
final 字段的使用方式很简单。在对象的构造器里为该对象的 final 字段赋值。不要 将正在创建过程中的对象引用写到一个其它线程可以看到的地方,这会让其它线程 在构造器尚未执行结束时就能访问该对象。如果遵循这个规则,当该对象被其它线 程看到时,这些线程总是能看到该对象 final 字段的正确值。且这些 final 字段所引 用的任意对象或数组的中的内容,至少是和 final 字段一样的新(译者注:final 字 段所引用的对象里的字段或数组元素可能在后续还会变化,若没有正确同步,其它 线程也许不能看到最新改变的值,但一定可以看到完全初始化的对象或数组被 final 字段引用的那个时刻的对象字段值或数组元素。)。