为什么java中的String是不可变的

本文是对《Why String is immutable in Java》的翻译
以下是原文地址:https://www.programcreek.com/2013/04/why-string-is-immutable-in-java/

在Java中,String是不可变的。不可变类就是其实例对象无法被修改的类。实例中的所有信息在创建实例的时候初始化,不可修改。不可变类有很多的优点。本文总结了为什么String被设计成不可变的。这篇文章从内存、同步和数据结构的角度阐述了不变性的概念。

1. String Pool 的需要
String Pool(String intern pool) 是Method Area中的一块特殊存储区。当创建字符串时,如果该字符串已经存在于池中,则将返回该字符串的引用,而不是创建新对象。
下面的代码会在堆中只创建一个String对象。

String string1 = "abcd";
String string2 = "abcd";
System.out.println(string1 == string2)  //true

如果String是可变的,使用一个引用更改字符串将导致其他引用的值错误

2. 缓存Hashcode
String的哈希值经常会被用到,例如在HashMap或HashSet中。不可变的特性保证了哈希值也是不可变的,这样它就可以被缓存而不用担心更改。这意味着,不需要在每次使用哈希值的时候都去计算,这样更有效率。
在String类中,有以下的代码:

private int hash; //该变量用来缓存哈希值

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包含不可重复的元素)。当然,上面的例子只是为了演示的目的,在真正的String类中没有value字段。
4. 安全性
String被广泛用作许多Java类的参数,例如,网络连接、打开文件等等。如果String是可变的,那么一个连接或文件可能被更改,从而导致严重的安全威胁。该方法认为它连接到一台机器,但不是。可变String也可能导致反射中的安全问题,因为参数是String。
以下是示例代码:

boolean connect(String s){
	if(!isSecure(s)){
	throw new SecurityException();
	}
	// 如果s在此之前使用其他引用更改,则会导致问题。
	causeProblem(s);
}

5. 不可变对象天生就是线程安全的
由于不可变对象不能被改变,所以它们可以在多个线程之间自由的共享。这消除了确保一致性的需求。

总之,出于效率和安全性的考虑,String被设计为不可变的。这也是为什么不可变类在许多情况下通常是首选的原因。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值