java小知识之不可不(immutable)类的设计

43 篇文章 0 订阅

一、不可变类简介

不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值。如JDK内部自带的很多不可变类:Interger、Long和String等。
可变类:相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类。

二、不可变类的优点

说完可变类和不可变类的区别,我们需要进一步了解为什么要有不可变类?这样的特性对JAVA来说带来怎样的好处?

  1. 线程安全
    不可变对象是线程安全的,在线程之间可以相互共享,不需要利用特殊机制来保证同步问题,因为对象的值无法改变。可以降低并发错误的可能性,因为不需要用一些锁机制等保证内存一致性问题也减少了同步开销。
  2. 易于构造、使用和测试

     

三、不可变类的设计方法

对于设计不可变类,个人总结出以下原则:

1. 类添加final修饰符,保证类不被继承

如果类可以被继承会破坏类的不可变性机制,只要继承类覆盖父类的方法并且继承类可以改变成员变量值,那么一旦子类以父类的形式出现时,不能保证当前类是否可变。

2. 保证所有成员变量必须私有,并且加上final修饰

通过这种方式保证成员变量不可改变。但只做到这一步还不够,因为如果是对象成员变量有可能再外部改变其值。所以第4点弥补这个不足。

3. 不提供改变成员变量的方法,包括setter

避免通过其他接口改变成员变量的值,破坏不可变特性。

4.通过构造器初始化所有成员,进行深拷贝(deep copy)

5.在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝

这种做法也是防止对象外泄,防止通过getter获得内部可变成员对象后对成员变量直接操作,导致成员变量发生改变。

package com.immutable;

public class ImmutableDemo {
    private final int[] myArray;  
    public ImmutableDemo(int[] array) {  
        this.myArray = array.clone(); // wrong  
    }
    
    public int[] get(){
    	return myArray.clone();
    }
}

以上代码就是一个不可变的对象,设计不可变对象的时候可以参考上面五个原则。

jdk的String类就是一个经典的不可变类,

深度克隆的实现方式:

对象实现Cloneable接口并重写Object类中的clone()方法(浅克隆方式);通过重写对象的clone方法,如果对象成员变量也是一个对象,需要递归实现clone()方法

对象实现Serializable接口,通过对象的序列化和反序列化实现克隆(此方法可以实现真正的深度克隆)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值