软件构造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类型时,尽量使用的地方都加上防御式拷贝.