java数据类型的Mutability与Immutability

1.    前言:

    (1) 改变一个变量、改变一个变量的值,二者有何区别? 

        改变一个变量:将该变量指向另一个值的存储空间。

        改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值。

    (2)“Change is a necessary evil.”变化是“罪恶”,但程序不能没有变化,

         要尽量避免变化,来避免程序中的副作用

    (3) 下面介绍java数据类型的Mutability与Immutability。

2.    不变性(Immutability):

    (1)不变性是一个重要的设计原则

    (2)不变数据类型:一旦被创建,其值不能改变。

    (3)如果是引用类型,也可以是不变的:一旦确定其指向的对象,就不能再被改变

            我们可以使用final关键字来实现这一点:

            

            a.    如果编译器无法确定final变量不会改变,就提示错误,这也是静态类型检查的一

                   部分。

            b.    所以,尽量使用 final变量作为方法的输入参数、作为局部变量。 

            c.    final表明了程序员的一种“设计决策”。

            需要注意的点:

                - final类无法派生子类

                - final类无法改变值/引用

                - final方法无法被子类重写

3.    不变性与可变性:

        满足不变性的对象:一旦被创建,始终指向同一个值/引用 

        满足可变性的对象:拥有方法可以修改自己的值/引用

(1)  例子:String与StringBuilder

        a.    String即为一个不可变的数据类型,一但创建,其值无法更改。

        b.    为了在一个String后面添加字符,需要新建一个String对象。

            例如:concat方法执行过程:

                    

        c.    而StringBuilder是一个可变类型,其具有修改内部值的方法。

            例如:append方法执行过程:

                

         d.    其之间的差异在只有一个引用指向该值时,没有区别。

            然而,在多个引用的时候,差异就出现了。

            

            t并不能改变s指向的值,而tb是可以改变sb指向的值的。

(2) 可变数据类型的优点与潜在风险:

    优点:

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

        最少化拷贝以提高效率。

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

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

    选取时,要进行折中,看你看中哪个质量指标。

    风险举例:

    a.    传递可变类型值时:

    

    该函数超出了spec范畴,因为其改变了输入参数的值。且这种错误非常难以跟踪和发现。

    对于其他程序员来说,也难以理解。

    b.    返回可变类型值时:


    在这种情况中,使用的Date是mutable的,因此对其返回值进行更改会导致其对象的值发生变化。

    要避免这点,就应该使用java.time中的其他immutable的类,如:LocalDateTime与Instant

    或者在返回date类型时,进行防御性拷贝:

(3)防御性拷贝

    接上面的例子2,通过防御性拷贝,给客户端返回一个全新的Date对象,这样就避免了表

    示泄露,即避免了对原数据的修改。

    但是:大部分时候拷贝不会被客户端修改, 可能造成大量的内存浪费。

              如果使用不可变类型,则节省了频繁复制的代价。

    

(4)安全地使用可变类型:局部变量,不涉及共享,只有一个引用。

         如果有多个引用(别名),使用可变类型就非常不安全。

         






            


            

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值