Java的String类为什么是不可变的以及字符串常量池

本篇文章内容参考自:

http://blog.csdn.net/renfufei/article/details/16808775

http://www.programcreek.com/2013/04/why-string-is-immutable-in-java/

http://www.jb51.net/article/49092.htm


JAVA中的String是一个不可变(immutable)类,即创建一个String对象后,是不能直接改变字符串中的某个字符的。

我们打开JDK中String类的源代码来看一下:

<span style="font-family:Microsoft YaHei;">/** The value is used for character storage. */
    private final char value[];</span>

其中用于存储String值的仍然是一个char型数组,并且注意到它是final修饰的,不可更改。


那么接下来思考为什么JAVA要把字符串设计成不可变类呢?有什么好处呢?

百度到了这样的文章:点击打开链接

文章说的非常好,建议阅读,我在这里再为大家总结一下:


String类是不可变类型的好处主要体现在两方面:效率安全


效率方面:

1、因为对象不可变,所以可以使用常量池的方式优化效率。在拷贝或者创建内容相同对象时,就不必复制内容本身,而是只要复制它的地址即可,复制地址只需要很小的空间和时间。只有不可变对象才能使用常量池,因为可以保证引用同一常量值的多个变量不产生相互影响。

2、因为对象不可变,所以String对象可以自身缓存HashCode。Java中String对象的哈希码被频繁地使用, 比如在hashMap 等容器中。字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存.这也是一种性能优化手段,意味着不必每次都去计算新的哈希码. 在String类的定义中有如下代码:

<span style="font-family:Microsoft YaHei;">private int hash;//用来缓存HashCode  </span>

安全性方面:

1、String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,还有反射机制所需要的String参数等, 假若String不是固定不变的,将会引起各种安全隐患
假如有如下的代码:

<span style="font-family:Microsoft YaHei;">boolean connect(string s){  
    if (!isSecure(s)) {   
throw new SecurityException();   
}  
    // 如果在其他地方可以修改String,那么此处就会引起各种预料不到的问题/错误   
    causeProblem(s);  
}  </span>


下面来详细分析一下常量池的思想,首先看常量池的示意图:

很明显只有不可变对象使用常量池,不然修改变量string1的值,string2的值也发生变化了。常量池的存在无疑大大降低了创建、拷贝等操作的时间复杂度和空间复杂度。由于平常编写的程序中,70%都是对字符串的操作,所以这个优化可以大大提升效率。

下面做实验体验这一点:


前三行打印结果为true,即s1、s2引用的对象的地址一样,说明两点,一是String类确实是不可变类,"ab"+"cd"被当做了新字符串而不是续接"ab"(不然"ab"和"abc"肯定不会地址一样),二是常量池确实存在,同是"abcd",所有对"abcd"的引用都指向同一地址。

后三行打印结果为false,原因应该是编译时,用new创建新对象会先于常量池判断,直接分配新地址。而这种写法很明显违背常量池设计初衷,所以我们可以看到IDE强力不推荐这种写法。




欢迎补充雅正!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值