为什么String是不可变的

String是Java中的不可变类。不可变类即其对象是不修改的,对象一旦建立,就不可改变。不可变类有许多优点,下面简要介绍一下String为什么是不可变类,对内存、同步、数据结构的认识会有助于理解。

1.String常量池的需要

常量池(String intern pool)是方法区(method area)中的一个特殊区域。当一个String被创建时,如果该字符串在常量池中已存在,那么将会返回该字符串对象的引用,而不是重新创建一个新String对象并返回其引用。

下面的代码只会在堆中创建一个对象:

String string1="abcd";

<span style="white-space:pre">	</span>String string2="abcd";
用一张图来说明:

java-string-pool

如果String是可变的,那么其中一个引用改变了字符串的值,将会导致另一个对该字符串的引用出错。

2.保存哈希码的需要

字符串的哈希码在Java中经常用到,如HashMap。不可变保证了哈希码永远是相同的,不必担心保存哈希码的改变。这样,就不必每次使用时都计算字符串的hashcode,保证了效率。

在String类里,有如下的代码:

<span style="white-space:pre">	</span>private int hash;//this is used to cache hash code
3.使其他对象的使用更加容易

为了更具体地说明,请看下面的代码:

HashSet<String> set = new HashSet<String>();

<span style="white-space:pre">	</span>set.add(new String("a"));
<span style="white-space:pre">	</span>set.add(new String("b"));
<span style="white-space:pre">	</span>set.add(new String("c"));
 
<span style="white-space:pre">	</span>for(String a: set)
	<span style="white-space:pre">	</span>a.value = "a";
在这个例子中,如果String是可变的,其值的改变就会引起set设计的冲突(set用来存储不重复的元素)。这个例子只是用来简单的说明,在真实的String类里没有value域。

4.安全性

String在许多java内置类里作为参数被广泛应用,如network connection,open files等等。如果String是可变的,将导致连接或文件面临严重的安全威胁。方法可能会将某个连接误认为是对某台机器的连接,但实际上可能是另一台机器的。同时,可变类也会影响反射的安全性。

下面是一个例子:

<span style="white-space:pre">	</span>boolean connect(string s){
    <span style="white-space:pre">		</span>if (!isSecure(s)) { 
<span style="white-space:pre">			</span>throw new SecurityException(); 
<span style="white-space:pre">		</span>}
    <span style="white-space:pre">		</span>//here will cause problem, if s is changed before this by using other references.    
    <span style="white-space:pre">		</span>causeProblem(s);
<span style="white-space:pre">	</span>}
5.不可变对象是天然线程安全的

因为不可变对象不能被修改,因此可以在多个线程间共享而不用进行任何同步的操作。


简单来说,String被设计为不可变类的原因就是效率和安全。这也是它被广泛使用的原因之一。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值