Java 字符串为何不可变

String 是 Java 中一个不可变的类,所以它一旦被实例化就无法被修改。不可变类的实例一旦创建,其成员变量的值就不能被修改。不可变类有很多优势。

一、字符串池

字符串池是 Java 运行环境方法区中的一部分特殊存储。当一个字符串被创建之时,首先会去这个字符串池中查找,如果找到直接返回对该字符串的引用。下面的代码只会在堆中创建一个字符串:

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

如果字符串可变的话,当两个引用指向指向同一个字符串时,对其中一个做修改就会影响另外一个。【请记住该影响,有助于理解后面的内容】

注意:
String s = new String(“abc”);创建了几个对象,有两种情况:
1.如果字符串常量池中有字符串 abc,那么只会在内存中创建一个对象(此对象是不能重复的);
2.如果字符串常量池中没有字符串 abc,那么在字符串常量池中创建一个内容为 abc 的对象,但是遇到了 new 关键字,则还是会在内存(不是常量池)中创建一个对象,然后将对象返回给引用 s,特别注意 s 不是一个对象。
说明:
Java 方法区中的字符串常量池,由 String 类维护。执行语句String s="abc"时,首先查看字符串池中是否存在字符串“abc”,如果存在则直接将“abc”赋给 s,如果不存在则先在字符串常量池中新建一个字符串“abc”,然后再将其赋给 s。

二、缓存 Hashcode

Java 中经常会用到字符串的哈希码(hashcode)。例如,在HashMap中,字符串的不可变保证了其 hashcode 永远保持一致,如此就可以避免一些不必要的麻烦。这也就意味着每次在使用一个字符串的 hashcode 的时候不用重新计算一次,更加高效。在 String 类中,有以下代码:

private int hash;//Cache the hash code for the string. 

hash 变量保存了 String 对象的 hashcode,因为 String 类不可变,所以一旦对象被创建,该 hash 值也无法改变。所以,每次想要使用该对象的 hashcode 的时候,直接返回即可。

三、使其他类的使用更加便利

如下代码:

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

如果字符串可以被改变,那么以上用法将有可能违反 set 的设计原则,因为 set 要求其中的元素不可以重复。上面的代码只是为了简单说明该问题,其实 String 类中并没有 value 这个字段值。

四、安全性

String 被广泛的使用在其他 Java 类中充当参数。比如网络连接、打开文件等操作。如果字符串可变,那么类似操作可能导致安全问题。因为某个方法在调用连接操作的时候,它认为会连接到某台机器,但是实际上并没有(其他引用同一 String 对象的值修改会导致该连接中的字符串内容被修改)。可变的字符串也可能导致反射的安全问题,因为它的参数也是字符串。代码示例:

boolean connect(string s){
    if (!isSecure(s)) { 
        throw new SecurityException(); 
    }
    //如果s在该操作之前被其他的引用所改变,那么就可能导致问题。   
    causeProblem(s);
}

五、不可变对象天生就是线程安全

因为不可变,所以它们可以自由地在多个线程之间共享,不需要任何同步处理。总之,String 被设计成不可变的主要目的是为了安全和高效。所以 String 类不可变,是一个很好的设计。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JFS_Study

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值