文档章节

Java不可变对象

從此迷花粉
 從此迷花粉
发布于 2017/05/09 11:24
字数 1196
阅读 16
收藏 0

不可变类:      所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值。即创建该类的实例后,该实例的属性是不可改变的。Java中的8个包装类和String类都是不可变类。所以不可变类并不是指该类是被final修饰的,而是指该类的属性是被final修饰的。
可变类:      相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类。

自定义不可变类遵守如下原则:

1、使用private和final修饰符来修饰该类的属性,这样只能对它们赋值一次;

2、提供带参数的构造器,用于根据传入的参数来初始化属性。通过构造器初始化所有成员,进行深拷贝(deep copy);

3、仅为该类属性提供getter方法,不要提供setter方法,在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝;

4、如果有必要,重写hashCode和equals方法,同时应保证两个用equals方法判断为相等的对象,其hashCode也应相等。

 

不变模式有两种形式:弱不变模式和强不变模式。

弱不变模式,指类实例的状态是不可改变,但是这个类的子类的实例具有可能会变化的状态,要实现弱不变模式,一个类必须满足下面条件:

  1. 对象没有任何会修改对象状态的方法 ,这样一来当对象的构造函数将对象的状态初始化之后,对象的状态便不再改变;
  2. 属性都是私有的,以防客户端对象直接修改内部状态;
  3. 这个对象所引用的其他对象如果是可变的话,必须设法限制外界对这些可变对象的访问,以防止外界修改这些对象,尽量在不可变对象内部初始化这些被引用的对象,而不要在客户端初始化再传入到不可变对象内部来,如果某个可变对象必须在客户端初始化,然后再传入到不变对象里的话,就应当考虑在不可变对象初始化的时候,将这个可变对象进行拷贝。

弱不变模式的缺点是,一个弱不变对象的子对象可能是可变的,这个可变的子对象可能可以修改父对象的状态,从而可能允许外界修改父对象的状态。

强不变模式:一个类的实例不会改变,同时它的子类的实例也具有不可变化的状态。一个类必须首先满足弱不变模式所要求的所有条件,并且还有满足下面条件之一:

  1. 类所有的方法都应当是final,这样这个类的子类不能够重写此类的方法;
  2. 此类本身就是final的,那么这个类就不可能会有子类,从而也就不可能有被子类修改的问题;

不变和只读的区别:当一个变量是只读时,变量的值不能直接改变,但是可以在其他变量发生改变的时候改变;比如生日是不变属性,而年龄是只读的,年龄会随着时间发生变化,生日则不会变化。(用final声明的变量是只读的)

不可变对象的好处:

  1. 不可变对象更容易构造,测试与使用;
  2. 真正不可变对象都是线程安全的;
  3. 不可变对象的使用没有副作用(没有保护性拷贝);
  4. 对象变化的问题得到了避免;
  5. 不可变对象的失败都是原子性的;
  6. 不可变对象更容易缓存,且可以避免null引用;
  7. 不可变对象可以避免时间上的耦合;

String,StringBuffer,StringBuilder都是final类,不允许被继承在本质上都是字符数组,不同的是,String的长度是不可变的而后两者长度可变,在进行连接操作时,String每次返回一个新的String实例,而StringBuffer和StringBuilder的append方法直接返回this,所以当进行大量的字符串连接操作时,不推荐使用String,因为它会产生大量的中间String对象。

StringBuffer和StringBuilder的一个区别是,StringBuffer在append方法前增加了一个synchronized修饰符,以起到同步的作用,为此也降低了执行效率;若要在toString方法中使用循环,使用StringBuilder。

 

© 著作权归作者所有

從此迷花粉
粉丝 7
博文 175
码字总数 63807
作品 0
海淀
程序员
私信 提问
深入理解Java中的不可变对象

深入理解Java中的不可变对象 不可变对象想必大部分朋友都不陌生,大家在平时写代码的过程中100%会使用到不可变对象,比如最常见的String对象、包装器对象等,那么到底为何Java语言要这么设计...

java菜分享
04/14
0
0
Java高并发--线程安全策略

Java高并发--线程安全策略 主要是学习慕课网实战视频《Java并发编程入门与高并发面试》的笔记 不可变对象 发布不可变对象可保证线程安全。 实现不可变对象有哪些要注意的地方?比如JDK中的S...

sunhaiyu
04/20
0
0
面试阿里常被问到的十个 Java 面试题

以满分十分来评估自己——你有多擅长 Java? 如果你并不完全确信你自己或是你对 Java 的熟练程度,那么这会是一个非常棘手的问题。如果有这种情况,你应该把打分调低一点。之后,你大概会得到...

小刀爱编程
2018/12/22
0
0
云妹总结了一些最最最常见的Java面试题供大家参考

云妹导读:String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的? String和StringBuffer、StringBuilder的区别 可变性 String类中使用字符数组:private final cha...

阿里云科技快讯
2018/08/17
0
0
Java 可变对象和不可变对象

一、简单定义 不可变对象(Immutable Objects)即对象一旦被创建它的状态(对象的数据,也即对象属性值)就不能改变,反之即为可变对象(Mutable Objects)。 不可变对象的类即为不可变类(Immuta...

JackieYeah
2014/03/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

0.01-Win10安装linux子系统

一、安装Debian子系统 -1、控制面板设置: -1.1、打开“控制面板” —— “程序” —— “启用或关闭Windows功能” —— 勾选 “适用于Linux的Windows子系统” -2、设置: -2.1、打开“设置”...

静以修身2025
昨天
2
0
init 0-6 (启动级别:init 0,1,2,3,4,5,6)

启动级别: init 0,1,2,3,4,5,6 这是个很久的知识点了,只是自己一直都迷迷糊糊的,今天在翻出来好好理解下。。 0: 停机 1:单用户形式,只root进行维护 2:多用户,不能使用net file system...

圣洁之子
昨天
2
0
Android Camera HAL浅析

1、Camera成像原理介绍 Camera工作流程图 Camera的成像原理可以简单概括如下: 景物(SCENE)通过镜头(LENS)生成的光学图像投射到图像传感器(Sensor)表面上,然后转为电信号,经过A/D(模数转...

天王盖地虎626
昨天
2
0
聊聊Elasticsearch的ProcessProbe

序 本文主要研究一下Elasticsearch的ProcessProbe ProcessProbe elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/process/ProcessProbe.java public class ProcessProb......

go4it
昨天
3
0
mysql PL(procedure language)流程控制语句

在MySQL中,常见的过程式SQL语句可以用在存储体中。其中包括IF语句、CASE语句、LOOP语句、WHILE语句、ITERATE语句和LEAVE语句,它们可以进行流程控制。 IF语句相当于Java中的if()...else if(...

edison_kwok
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部