immutable和mutable类型数据

先分析在Java中的数据类型。

基本数据类型对象数据类型

int,long,byte,short,char,

float,double,boolean

Classes,interfaces,arrays,enums,

annotations

只有值,没有ID,与其他值无法区分既有ID也有值
都是immutable类型有些是mutable类型,有些是immutable
在栈中分配内存在堆中分配内存,ID存在栈中,指向数据
无法实现表达的统一表达式与泛型的统一
实现代价低代价昂贵

那什么是immutable和mutable类型的数据呢?

immutable类型的数据一旦被创建,就始终指向同一个值/引用。

 String是immutable类型的典型例子。一旦被创建,一个String对象的值始终不变。

如果想要在String的结尾添加字符,也就是改变String类型变量的值,就必须生成一个新的String对象,使变量指向那个对象。

mutable类型数据拥有方法可以修改自己的值/引用。

比如StringBuilder,它本身有删除,嵌入和代替串中字符的方法。它可以直接修改对象的值,而不是像immutable类型数据,需要创建一个新的对象。

 那immutable类型和mutable类型数据的差别在哪?

当只有一个引用指向该值时,这两者是没有区别的。因为修改后的值都是一样的。

但当有多个引用的时候,差异就出现了。

如下图

 当另一个变量t指向与s相同的字符串对象,而另一个变量tb指向与sb相同的StringBuilder时,不可变对象和可变对象之间的差异变得更加明显。

如果使用immutable类型数据,对其频繁修改会产生大量的临时拷贝,因为每次修改都要创建一个新的对象,使变量指向它,这些临时拷贝最后都需要垃圾回收。

而使用mutable类型数据就没有这方面的担忧,因为它有方法直接修改对象的值,可以最少化拷贝来提高效率。

使用mutable类型数据,可获得更好的性能,在多个模块间共享数据也很方便。

经过上面的论述,那既然mutable类型的功能好像比immutable类型更加强大,那为什么还要强调使用immutable类型数据呢?

这就涉及到编程的安全性,编程首先便是考虑程序的安全性。

因为如果使用mutable类型数据,当多个引用同时指向同一个对象时,每个引用的操作都会改变对象的值,此时就容易使程序乱套。

如图,令t=s,然后对t进行操作,打印s,仍可以得到对t做出改变的结果。

而immutable类型数据就没有这种后顾之忧。当然,使用哪种数据类型需要根据当前情况考虑,如果是需要频繁修改的数据,当然是使用mutable类型数据更好。这需要看你程序的要求,对数据的要求更看重哪个质量指标。

再者,比如在使用Date这个mutable类型的对象,若直接return,就有可能导致函数外的操作能改变函数内的值,这就会发生错误。所以这种时候通常会使用一种叫做防御式拷贝的方法,给客户端返回一个全新的Date对象,即return new Date()。这样就能防止上面的情况。但大部分时候该拷贝不会被客户端修改,可能造成大量的内存浪费,这种情况下使用immutable类型,就可以节省频繁复制的代价了。

最后再提及一个final类型的变量。被final修饰的变量,始终只能指向同一个对象。如果final修饰的是一个immutable类型,由于immutable类型无法改变值,只能通过创建一个新的存储空间来存放新的值,故被final修饰后,它便无法改变其值,任何改变的操作都会报错。而若final修饰的是一个mutable类型数据,它便不能再指向另外一个对象了。

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值