软件构造05

可变(mutable)类型的可怕

关于一个小例子引发的想法:

为什么mutable类型如此可怕?

因为一旦有多个别名指向同一个变量,就会引起牵一发而动全身的影响.
我们来看:

List<String> lst1=new List<>();
List<String> lst2=lst1;

对于可变类型:

lst2=lst1;

这一句意味着lst2和lst1都指向了同一个对象,从此通过任何一个别名引起的变化两边都会改变!!!!!

最细微的难以察觉的带来的bug是函数传递

接下来看这个构造方法造成泄露的小例子:

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class test2 {

   public static void main(String[] args) {
       List<String> lst1=new ArrayList<>();
       lst1.add("a");
       lst1.add("b");
       lines l=new lines(lst1);
       System.out.println(l.get(0));
       lst1.remove("a");
       System.out.println(l.get(0));

   }
}
class lines
{
   private List<String> lst;
   public lines(List<String> lst)
   {
       this.lst=lst;
   }
   public String get(int index)
   {
       return lst.get(index);
   }
   public void addString(String str)
   {
       this.lst.add(str);
   }
}

lines中lst这个可变类型在构造函数时粗暴的使用了this.lst=lst
导致类内的lst会跟你传进来的那个list挂钩!!!!
当你改变传进来的那个list对象时,你构造的lines类的那个对象的类内lst成员也会跟着改变!!!!
而这,仅仅是我们在 构造函数 时的疏忽,十分可怕.
我们来看以下上面那个例子的输出结果:

我们看到了构造方法造成的泄露.
因此,不仅仅是在函数返回时,当我们使用mutable类型时,尽量使用的地方都加上防御式拷贝.

posted on 2022-06-14 21:15  岳思源  阅读(78)  评论(0编辑  收藏  举报