final关键字
修饰类,该类不可被继承
修饰方法,该方法不能被复写
final方法比非final方法要快,因为在编译的时候已经静态绑定了,不需要在运行时再动态绑定。其实final带来的性能提升非常有限。jvm官方文档也没有明白说明final在性能方面的好处。
tips: 类的private方法会隐式地被指定为final方法。修饰属性
final修饰属性则该类的属性不会隐式的初始化(类的初始化属性必须有值),或者在构造函数中初始化。(不会隐式初始化是不可变对象所有属性必须为final的关键)修饰变量,只能赋一次值,变为常量
不可变对象
- final修饰class,不可被继承
- 重要重要:所有字段都是final修饰 是有final修饰不仅仅是从语义上说明被修饰字段的引用不可改变 更重要的是这个语义在多线程环境下由Java内存模型保证被修饰字段所引用对象的初始化安全 既final修饰字段在其他线程可见时 它必定是初始化完成的 相反 非final修饰字段由于缺少该保证 可能到一个线程看到一个字段的时候 其未被初始完成 从而导致一些可变预料的情况
- 不提供setter方法,属性的暴露都是以深拷贝的方式。
- 构造自己的属性时,也是深拷贝够早的,不然相同的引用外界仍然可以修改。
不可变对象的严格要求:
类本身是有final修饰 防止子类改变其定义的行为
所有字段都是final修饰 是有final修饰不仅仅是从语义上说明被修饰字段的引用不可改变 更重要的是这个语义在多线程环境下由Java内存模型保证被修饰字段所引用对象的初始化安全 既final修饰字段在其他线程可见时 它必定是初始化完成的 相反 非final修饰字段由于缺少该保证 可能到一个线程看到一个字段的时候 其未被初始完成 从而导致一些可变预料的情况
在对象创建时 this关键字没有泄露 防止其他类在对象创建过程中修改其状态
任何字段 若其引用了其他状态可变的对象 则这些字段必须是私有修饰的 并且这些字段值不能对外暴露 若相关方法要返回这些字段值 应该进行防御式复制
当对象为不可变对象时,一定是线程安全的
- 同时对一组相关的数据进行写操作,需要保证原子性,将这一组数据封装进一个不可变对象,并以volatile修饰对象变量,避免了加锁形式的严格并发控制
- 如果以对象作为hashmap的key,对象如果可变,可能导致对象变化之后hashcode改变,同一个对象在hashmap找不到其索引的值了。