1.1 定义

  不可变类(Immutable Objects):当类的实例一经创建,其内容便不可改变,即无法修改其成员变量。

  可变类(Mutable Objects):类的实例创建后,可以修改其内容。

  Java 中八个基本类型的包装类和 String 类都属于不可变类,而其他的大多数类都属于可变类。

  ps: 某个对象在被创建后其状态就不能被修改,那么这个对象就称为不可变对象,不可变对象一定是线程安全的。不可变对象很简单。他们只有一种状态,并且该状态由构造函数来控制。

  需要特别注意的是,不可变类的不可变是指该类的实例不可变而非指向该实例的引用的不可变

1.2 充分条件

当满足以下条件时,对象才是不可变的:

(1)对象创建以后其状态就不能改变;

(2)对象的所有域都是final类型;

(3)对象是正确创造的(在对象创建期间,this引用没有溢出)。

1.3 特征

一个不可变类的定义应当具备以下特征:

  1. 所有成员都是 private final 的
  2. 不提供对成员的改变方法,例如:setXXXX
  3. 确保所有的方法不会被重载。手段有两种:使用final Class(强不可变类),或者将所有类方法加上final(弱不可变类)。
  4. 如果某一个类成员不是基本类型(primitive type)或不可变类,必须通过在成员初始化(in)或者getter方法(out)时通过深度拷贝(即复制一个该类的新实例而非引用)方法,来确保类的不可变。
  5. 如果有必要,重写hashCode和equals方法,同时应保证两个用equals方法判断为相等的对象,其hashCode也应相等。

1.4 优缺点

1. 优点:效率和安全。

  • 效率(拷贝地址+缓存)

      1. 当一个对象是不可变的,那么需要拷贝这个对象的内容时,就不用复制它的本身而只是复制它的地址,复制地址(通常一个指针的大小)只需要很小的内存空间,具有非常高的效率。同时,对于引用该对象的其他变量也不会造成影响。

      2. 不变性保证了hashCode 的唯一性,因此可以放心地进行缓存而不必每次重新计算新的哈希码。而哈希码被频繁地使用, 比如在hashMap 等容器中。将hashCode 缓存可以提高以不变类实例为key的容器的性能。

  • 线程安全

      在多线程情况下,一个可变对象的值很可能被其他进程改变,这样会造成不可预期的结果,而使用不可变对象就可以避免这种情况同时省去了同步加锁等过程,因此不可变类是线程安全的。

2. 缺点:不可变类的每一次“改变”都会产生新的对象,因此在使用中不可避免的会产生很多垃圾。

最新文章

  1. 分享一些自己的学习过程和学习方法(来自daimajia)
  2. Html特殊字符表
  3. Dapper 数据操作框架
  4. Android Studio2.0 教程MAC版 -快捷键篇
  5. [游戏模版7] Win32 最简单贴图
  6. Android开源项目发现---ViewPager 、Gallery 篇(持续更新)
  7. 邮件发布google blogger 博客
  8. 如何免费使用jrebel 和eclipse 项目配合完成热部署功能
  9. 第一个ExtJS练习(添加用户面板)
  10. phpcms v9 sql注入脚本
  11. OSS网页上传和断点续传(终结篇)
  12. python中字典的用法
  13. 查看cookie的快捷方法
  14. Jenkins进阶-部署Web项目到远程tomcat(7)
  15. jvm系列(八):jvm知识点总览
  16. trust zone之我见【转】
  17. setting.xml配置文件 --转载
  18. LightOJ - 1396 :Palindromic Numbers (III)(逐位确定法)
  19. 使用jQuery通过点击它删除HTML表格行-超简单
  20. 洛谷 P3378 【模板】堆

热门文章

  1. 《Spring Cloud微服务 入门 实战与进阶》
  2. vscode源码分析【四】程序启动的逻辑,最初创建的服务
  3. 通过组件实现相同group下字符串拼接
  4. CNN反向传播更新权值
  5. C# rename files
  6. Linux下载——下载文件的命令
  7. 反射DataTable转实体类
  8. 区块链社交APP协议分析:BeeChat
  9. contentOffset、contentSize和contentInset
  10. 【转载】不可不知的 Android strings.xml 那些事