哈尔滨工业大学软件构造心得之Immutable对象(二)

目录

1.Immutable对象和mutable对象基本概念

不可变对象有几个优点:

Java中不可变对象的经典例子就是String类的实例:

2.Java mutable 和 immutable类型

举例

3.如何保证自己创建的类是immutable类

4.可变与不可变的优缺点

5.深度拷贝


1.Immutable对象和mutable对象基本概念

在面向对象和函数式编程中,一个immutable对象(不可变对象)是指一旦创建之后状态不可改变的对象。

mutable对象(可变对象)是指创建之后也可以修改的对象。

在有些情况下,对象也被认为是不可变的(immutable),即,一个对象包含的内部使用的属性改变了,但从外部看对象的状态并没有改变。

例如,一个使用memoization来缓存复杂计算结果的对象仍然被看作是不可变(immutable)对象.

在面向对象编程中,String 以及其他的具体对象都被看作是不可变(immutable)对象,以提高可读性和运行效率。

不可变对象有几个优点:

线程安全

易于理解

比可变对象有更高的安全性

Java中不可变对象的经典例子就是String类的实例:

String s="ABC";

s.toLowerCase();


尽管String类声明中没有提供让它成为不可变对象的语法,但是,String类的方法中没有方法去改变一个String包含的数据,这就使得它是不可变的。toLowerCase()方法不会改变s中包含的数据“ABC”。而是创建一个新的String对象并将其初始化为“abc”,然后返回这个新对象的引用。

Java中关键字final用于声明原始数据类型(primitive types)和对象引用为不可变对象,但是它不能使对象本身变为不可变对象。

原始数据类型(primitive types)变量(int, long, short等)定义之后还可以再重新赋值,可以使用final阻止这样的赋值。

int i=42;//int is of primitive type

i=43;//OK

final int  j=42;//

j=43; // does not compile.j is final so can't be reassigned

仅仅使用final关键字还不能让引用类型(reference types)成为不可变对象,final只能阻止重新赋值。

final MyObject m=new MyObjecct();//m is of reference type

m.data=100;//OK.We can change state of object m(m is mutable and final doesn't change this fact)

m=new MyObject();//does not compile.m is final so can't be reassigned


2.Java mutable 和 immutable类型

原始类型包装类(primitive wrappers)(Integer,Long, Short, Double, Float, Character, Byte, Boolean)也都是不可变的。

含义解释

immutable : variables that are assigned once and never reassigned.

mutable : When you assign to a variable or a field, you're changing where the variable's arrow points. You can point it to a different value. When you assign to the contents of a mutable value – such as an array or list – you're changing references inside that value.

基本类型及其封装对象类型都是不可变的

举例

例如String和StringBuilder:

1. String是immutable的,每次对于String对象的修改都将产生一个新的String对象,而原来的对象保持不变。

2. StringBuilder是mutable,因为每次对于它的对象的修改都作用于该对象本身,并没有产生新的对象。

3.如何保证自己创建的类是immutable类

  • 所有成员都是private final。
  • 不提供对成员的改变方法,setXX
  • 确保所有的方法不会被重写。手段有两种:使用final Class(强不可变类),或者将所有类方法加上final(弱不可变类)。
  • 如果某一个类成员不是原始变量(例如int,double)或者不可变类,必须通过在成员初始化或者使用get方法时要通过深度拷贝方法,来确保类的不可变。

4.可变与不可变的优缺点

使用不可变类型,对其频繁修改会产生大量的临时拷贝(需要垃圾回收) ;

可变类型最 少化拷贝以提高效率。

使用可变数据类型,可获得更好的性能 ,也适合于在多个模块之间共享数据 。例如全局变量。

不可变类型更“安全”, 在其他质量指标上表现更好。

对可变类型可能造成的风险,我们通过防御式拷贝(深度拷贝),给客户端返回一个全新的可变类型的对象,大部分时候该拷贝不会被客户端修改, 可能造成大量的内存浪费。

5.深度拷贝

当只是引用传递或者根据对象的值创建新的值,称为“浅复制”,当原对象的发生改变时,根据上面方式创建的新对象的也会随之改变;

而如果采用深度复制,那是真正的复制了一份新的对象,新对象的与原对象不存在任何关联,原对象发生改变不会影响新对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值