不可变对象&final关键字

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找不到其索引的值了。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,839评论 18 399
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,418评论 11 349
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,324评论 9 118
  • 最近使用scrollTo和scrollBy时候发现,是不可以直接传入负数的了。以前一直是可以的,网上全部直接写负数...
    rivc阅读 1,027评论 1 2
  • 自从矫正牙齿,花费很多后。我已经很少购物,吃美食了。今天,表妹来京,终于可以和她们一起买买买吃吃吃了。 和她们...
    瑾熙的月亮阅读 196评论 0 0