Java中的字符串是不可变的原因

字符串在Java中是不可变的。

不可变类就是一个实例不能被修改的类。

创建实例时初始化实例中的所有信息,并且不能修改该信息。

1.字符串池的要求:

字符串池(字符串特定池)是方法区域中的一个特殊存储区域。当创建字符串时,如果字符串已经存在于池中,则将返回现有字符串的引用,而不是创建新对象。

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

String string1 = "abcd";

String string2 = "abcd";

如图 

2.缓存Hashcode:

在Java中,字符串的Hashcode经常被用到。例如,在一个HashMap或HashSet。一成不变的保证hashcode永远是相同的所以它可以兑现,不用担心变化。这意味着,不需要计算hashCode每次使用它。这更有效。

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

1

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

 3.经常使用其他对象:

为了说明这个问题,考虑下面的程序:

1

2

3

4

5

6

7

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";

在这个例子中,如果字符串是可变的,它的值是可以改变的,将违反设计集(包含非重复元素)。当然,上面的示例仅用于演示目的,在真正的字符串类中没有值字段。

4.安全:

字符串被广泛用于许多java类的参数,如网络连接、打开文件、字符串等都不是一成不变的,一个连接或文件将被改变,这可能导致严重的安全威胁。方法认为它是连接到一台机器,但不是。可变字符串也可能导致反射中的安全问题,因为参数是字符串。

代码如下:

1

2

3

4

5

6

7

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.不可变对象自然是线程安全的:

因为不可变对象不能更改,所以可以在多个线程之间自由共享。这消除了进行同步的要求。

总之,字符串是为了效率和安全原因而不可变的。这也是为什么在很多情况下首选类是不可变类的原因。

从源码看:

1.String类本身是final修饰的

2.数组也是final修饰的 private 修饰的

3.整个类没有提供任何一个修改数组内容,以及返回数组引用的方法

参考:为什么Java中的字符串是不可变的? - jacunjpg - 博客园 (cnblogs.com)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值