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

Java 基础系列:不变性的更多相关文章

  1. Java基础系列-ArrayList

    原创文章,转载请标注出处:<Java基础系列-ArrayList> 一.概述 ArrayList底层使用的是数组.是List的可变数组实现,这里的可变是针对List而言,而不是底层数组. ...

  2. 2015年12月28日 Java基础系列(六)流

    2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流

  3. Java基础系列--static关键字

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/8477914.html 一.概述 static关键字是Java诸多关键字中较常使用的一个,从 ...

  4. Java基础系列-Collector和Collectors

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10748925.html 一.概述 Collector是专门用来作为Stream的coll ...

  5. Java基础系列-二进制操作

    原创文章,转载请标注出处:<Java基础系列-二进制操作> 概述 Java源码中涉及到大量的二进制操作,非常的复杂,但非常的快速. Java二进制表示法 首先了解下二进制,二进制是相对十进 ...

  6. Java基础系列-equals方法和hashCode方法

    原创文章,转载请标注出处:<Java基础系列-equals方法和hashCode方法> 概述         equals方法和hashCode方法都是有Object类定义的. publi ...

  7. Java基础系列-Comparable和Comparator

    原创文章,转载请标注出处:<Java基础系列-Comparable和Comparator> 一.概述         Java中的排序是由Comparable和Comparator这两个接 ...

  8. Java基础系列--HashMap(JDK1.8)

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10022092.html Java基础系列-HashMap 1.8 概述 HashMap是 ...

  9. 夯实Java基础系列1:Java面向对象三大特性(基础篇)

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...

  10. 夯实Java基础系列3:一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!

    目录 目录 string基础 Java String 类 创建字符串 StringDemo.java 文件代码: String基本用法 创建String对象的常用方法 String中常用的方法,用法如 ...

随机推荐

  1. Salesforce 开发整理(一)测试类最佳实践

    在Sales force开发中完善测试类是开发者必经的一个环节,代码的部署需要保证至少75%的覆盖率,那么该如何写好测试类呢. 测试类定义格式如下: @isTest private class MyT ...

  2. 黑科技,利用python拨打电话,控制手机技术!

    跟selenium操作浏览器原理类似,这是用appium操作移动设备的一个自动化功能,自娱自乐,主要是通过小案例引出相关技术 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很 ...

  3. Sql 代码规范说明

    对于程序工作者来说,代码的阅读必不可少,好的代码让人读起来一目了然.神清气爽,做代码调试也可以很开的捋顺逻辑定位问题,但是如果遇到一些可读性较差,毫无规矩可言的代码,那真的比吃了翔都难受啊,如果再让你 ...

  4. 在dubbo的一端,看Netty处理数据包,揭网络传输原理

    如今,我们想要开发一个网络应用,那是相当地方便.不过就是引入一个框架,然后设置些参数,然后写写业务代码就搞定了. 写业务代码自然很重要,但是你知道: 你的数据是怎么来的吗?通过网络传输过来的呗. 你知 ...

  5. 在.net 程序中使用Mustache模板字符串

    今天弄了一个配置随着使用环境动态切换的功能,一个基本的思路是: 将配置配置为模板的形式, 根据不同的环境定义环境变量 根据环境变量渲染模板,生成具体的配置 这里面就涉及到了一个字符串模板的功能,关于模 ...

  6. wpf datetime format

    <Style TargetType="{x:Type DatePickerTextBox}"> <Setter Property="Control.Te ...

  7. SPA项目开发之动态树、表格、分页

    思路: 1.准备好后台(左侧树,带分页的文章查询) 2.将左侧树的数据绑定到elementui中的menu标签上 3.新增一个自定义组件用来展示文章列表的 4.绑定elementui提供的分页组件来完 ...

  8. JQuery操作样式以及JQuery事件机制

    1.操作样式     1.1 css的操作     功能:设置或者修改样式,操作的是style属性 操作单个样式 // name:需要设置的样式名称 // value:对应的样式值 // $obj.c ...

  9. swift个人总结

    最近iOS10 已经开始正式使用,研究使用了swift3.0,将一些总结记录于此,以便以后查阅.持续更新中. swift中一般将一些功能相近的方法写在同一个延展中,便于代码的规范,找起来也方便.区别o ...

  10. 【jQuery】jQuery基础

    jQuery介绍 jQuery是一个轻量级JS库,使用十分简单: jQuery的核心是选择器,用于获取页面元素: jQuery提供了大量高效的方法,开发速度大幅提升: jQuery选择器 jQuery ...