软件构造课程心得——mutable和immutable类型

软件构造课程心得——mutable和immutable类型

当说到数据类型,一个难以绕开的分类就是mutable和immutable类型数据,即可变数据类型和不可变数据类型。下面就具体介绍一些我个人对这两种数据类型的理解和感悟。

一、可变数据类型与不可变数据类型的定义

可变数据类型是指数据类型可以通过该数据类型的一些方法来改变数据类型内部的值,改变内部数据的方法我们称为mutator(变值器),它的返回值往往是void,说明它的主要任务就是改变数据内部的表示。
而不可变数据类型则一旦进行实例化后就无法在改变其内部的值,至少在外界看来是如此。不可变数据类型没有mutator(变值器),无法从外部对其值进行改变。当然,即使这样我们也不能拍着胸脯说这个类型的数据确实是不可改变的——如果有表示泄露(rep exposure),不可变类型的数据将变得极为不安全。为了防止表示泄露,我们在对外提供数据的一些内部数据时,一定要注意这个数据是否为可变类型,因为如果通过可变类型将原本不应该改变的数值进行改变将不可控。为了保证即使是可变的内部数据也不会导致immutable类型是内部数据遭到改变,就应当使用防御式编程,即返回的数据不是内部数据本身,而是它的一个副本,即使这个副本发生了改变也不会导致原本的数据发生变化。
总而言之,不可变数据类型自创建以来内部数据就不会再发生改变,而可变数据类型的内部数据是有专门的方法进行改变的。

二、可变数据类型与不可变数据类型的优劣

可变数据类型十分灵活,可以随我们的需求进行改变,但是很容易由于其不当的改变而导致程序出现问题;而不可数据类型由于不能改变值,较为稳定,但也由于太过稳定,需要值不同的数据时只能重新建立一个对象,有时会白白浪费很多存储空间。由于以上的优劣分析,我们在进行程序设计时,最好优先使用不可变数据类型,避免因为考虑不周而造成不必要的安全问题。在确实有必要的情况下再使用可变数据类型,但也一定要考虑安全性,留个心眼防范问题发生。

但无论是可变还是不可变数据类型,防止表示泄露都是十分重要的事情,因为表示泄露会使得我们的程序变得不可控,即使是可变数据类型,我们也应当将所有的变化限制在mutator方法中,让mutator成为变化唯一“合法”的途径,这样可以在今后的debug中起到不小的作用。

三、可变数据类型与不可变数据类型的等价性

等价性在可变数据类型中体现为观察等价性和行为等价性,在不可变数据类型中体现为引用等价性和对象等价性。在我看来,观察等价性和引用等价性考虑的都是数据类型在内存中的地址引用,地址相同即为等价,不相同即为不等价,这也是判断等价最简单也是最原始的比较方法。但是在应用中,我们判断等价性往往无法达到如此严格,往往是rep相同,或者rep的一部分相同就可以认为二者是等价的,这种等价性判断我们用equals方法来实现,不基于地址引用而基于使用相同的方法能否保持一致性的等价性判断就是行为等价性或对象等价性。

四、可变数据类型与不可变数据类型的克隆

前面提到了使用防御式拷贝来防止表示泄露,那么十分值得注意的就是克隆的两种类型:深拷贝和浅拷贝。顾名思义,深拷贝相对来说比较彻底,是重新构造一个与原值完全相同的对象;而浅拷贝只是多构造了一个对象的引用出来,本质上对象还是原先的那一个。浅拷贝的副本发生变化,原来的对象也会跟着变化,而深拷贝的副本和原本的对象将不会有任何关系。因此我们在进行防御式拷贝时一定要选择深拷贝,浅拷贝同样会有表示泄露的风险。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值