1.什么是不可变对象
如果一个对象在创建之后就不能再改变它的状态,那么这个对象是不可变的(Immutable)。不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型变量的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。
2.final关键字的作用
如果要创建一个不可变对象,关键一步就是要将所有的成员变量声明为final类型。所以下面简单回顾一下final关键字的作用:
-
final修饰类,表示该类不能被继承,俗称断子绝孙类,该类的所有方法自动地成为final方法
-
final修饰方法,表示子类不可重写该方法
-
final修饰基本数据类型变量,表示该变量为常量,值不能再修改
-
final修饰引用类型变量,表示该引用在构造对象之后不能指向其他的对象,但该引用指向的对象的状态可以改变
3.String类不可变性的分析
public class Test {
public static void main(String[] args) {
String name = "KEKE";
name = "TEST";
}
}
很显然,上述代码name值的结果为“TEST“,但通过赋值操作我们发现我们可以更改字符串变量的值,这种改变并不能推翻“字符串不可变性”中的不可变。
也就是说字符串变化并不指的是赋值这种变化。
那么我们通过字符串类型和值类型在内存中的存储方式对比看看,字符串中的不可变到底指的是什么。
值类型:
字符串:
不可变性:当你给一个字符串重新赋值之后,老值并没有在内存中销毁,而是重新开辟一块空间存储新值。
如果我们在实际开发中对很含有大量字符的字符串进行遍历赋值修改,会对内存中产生很多无法释放的字符串对象,造成内存垃圾。
堆内存中字符串对象可以用于(指向)多个字符串变量
当代码中存在多个不同的字符串变量,它们存储的字符值都是相同的时候。
这些变量存储的字符串不会每一个都单独去开辟空间,而是它们共用一个字符串对象,共同的指向了内存中的同一个字符串引用。