为什么在Java中String是不可变的?

String在Java中是不可变的。不可变类只是其实例无法修改的类。创建实例时实例中的所有信息都会初始化,并且无法修改该信息。不变类有很多优点。本文总结了为什么String被设计为不可变的。这篇文章从内存,同步和数据结构的角度说明了不变性概念。

1.字符串池的要求

字符串池(String intern pool)是“ 方法区”中的特殊存储区。创建字符串时,如果该字符串已存在于池中,则将返回现有字符串的引用,而不是创建新对象。

以下代码将在堆中仅创建一个字符串对象。

String string1 = "abcd";
String string2 = "abcd";

外观如下:

如果字符串是可变的,则用一个引用更改字符串会导致其他引用的值错误。

2.缓存哈希码

字符串的哈希码在Java中经常使用。例如,在HashMap或HashSet中。不可变保证哈希码始终是相同的,因此无需担心更改即可将其兑现,这意味着无需每次使用哈希码就可以计算出来。这样更有效。

在String类中,它具有以下代码:

private int hash;//this is used to cache hash code.

3.促进其他对象的使用

要具体说明,请考虑以下程序:

HashSet<String> set = new HashSet<String>();
set.add(new String("a"));
set.add(new String("b"));
set.add(new String("c"));
 
for(String a: set)
	a.value = "a";

在此示例中,如果String是可变的,则可以更改其值,这将违反set的设计(set包含未重复的元素)。顺带一提,上面的示例仅用于演示目的,value在实际的字符串类中没有任何字段。

4.安全性

字符串被广泛用作许多Java类的参数,例如网络连接,打开文件等。如果字符串不是不可变的,则连接或文件将被更改,这可能会导致严重的安全威胁。该方法认为它正在连接到一台机器,但没有。因为参数是字符串,所以可变字符串也可能在反射中引起安全问题。

这是一个代码示例:

boolean connect(string s){
    if (!isSecure(s)) { 
throw new SecurityException(); 
}
    //here will cause problem, if s is changed before this by using other references.    
    causeProblem(s);
}

5.不可变对象自然是线程安全的

由于不可变对象无法更改,因此可以在多个线程之间自由共享它们。这消除了进行同步的要求。

总而言之,String出于效率和安全性原因而设计为不变的。这也是通常在很多情况下首选不可变类的原因。

喜欢这篇文章的可以点个赞,欢迎大家留言评论,记得关注我,每天持续更新技术干货、职场趣事、海量面试资料等等
如果你对java技术很感兴趣也可以交流学习,Java技术资料交流qq裙:907135806,共同学习进步。
不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!
还有奉上我近期整理出来的一套完整的java架构思维导图,可供大家对照知识点参考学习。
Java架构最全学习路线图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值