JAVA的可变类与不可变类

概念

  • immutable:一旦创建就不能改变其值和引用。
  • mutable:创建之后,该对象拥有可以更改其值/引用的方法,可以利用这些方法改变。

改变引用:将该变量指向另一个值的存储空间。
改变值:将储存空间内储存的信息改变。

String的例子是最常见的,String是一个不可变类,当我们对一个String进行修改时,他并不会对当前储存空间内的字符串进行修改,而是新开一个储存空间存放新串,然后将引用转到当前这个新开的储存空间。于此产生对比的就是StringBuilder,它是可变类,当我们对其进行修改时,其引用不会发生任何变化,但是它的储存空间的值会被修改。对于后者的修改有一个很大的隐患,就是如果我们有两个StringBuilder指向同一个对象的话,那么我们对其中一个进行修改,另一个也就会跟着改变这是一个十分可怕的后果。

final声明

final究竟声明了什么?
如果当前变量为基础变量,那么final可以使其值不会发生改变。如果是一个类,那么可以保证其对象的引用不会发生改变,但是不能保证其对象是否改变。

1
2
3
final StringBuffer a=new StringBuffer("immutable");
final StringBuffer b=new StringBuffer("not immutable");
a=b;

这样的代码就会编译错误,因为他在试图修改一个经过final修饰的引用。

1
2
final StringBuffer a=new StringBuffer("immutable");
a.append(" broken!");

而这样的代码编译是可以通过的,因为他只是取修改一个final的引用的值,是被允许的。

immutabel的构建

  1. 类声明为final,不可以被继承
  2. 所有成员是私有的,不允许直接被访问
  3. 对变量不要setter方法
  4. 所有可变的变量是final的,只能赋值一次
  5. 通过构造器初始化所有成员,进行深拷贝
  6. 在getter方法中不能返回对象本身,返回对象的拷贝