Java中的不可变对象(String为例)
Java中的不可变对象都有final作为修饰符,其中最为典型的就是String,今天就已String为例谈谈自己对于Java中不可变对象的理解,不足之处还望海涵
作为初学者在阅读书籍时经常容易混淆的地方就是String对象的不可变性,本人就在学习过程中遇到了这样的疑惑。既然String是不可变的那么以下这行代码的输出结果就令人十分不解。
’‘’
String a = "hello";
a = "sonny";
System.out.println(a);
//a的输出结果为sonny
‘’‘
想当然,既然你说String不可变,为什么我将一个新值赋给a后a的输出结果发生了改变呢?
在查阅了相关资料和读了许多前人的文章后,我发现自己搞混了一点,String的确是不可变,但是不可变指的是“hello”这个对象,而非前面的String a,a是对象变量而非对象本身,在创建了“hello”对象后,Java的虚拟机就为其在虚拟内存中找了一个位置储存,在整个运行过程中从在再不会对其更改。
’‘’
String a = "hello";
String b = a;
a = "sonny";
System.out.println("a的hash: "+a.hashCode()+" b的hash:"+b.hashCode());
a = "hello";
System.out.println("a的hash: "+a.hashCode()+" b的hash:"+b.hashCode());
//a的hash: 109620957 b的hash:99162322
//a的hash: 99162322 b的hash:99162322
‘’‘
根据以上代码我们可以发现,不同的对象变量有相同的字符串对象时,其Hash码(可以认为是其地址)。由此可知字符串对象并非将其本身复制并传给不同变量,而仅仅是将地址传递给他们。
这也引出了Java这样设计的好处。
优势:
-
高效,只复制地址而不用复制对象本身节省了大量时间
-
安全,尤其是在多线程操作时,可变对象可以被任意一个线程修改,在成无法预知的后果