您现在的位置:主页 > java下午茶 > >

为什么在Java中String被设计成不可变



时间: 2014-08-26 10:45     来源 : IT学习者      点击:

关键词: java    String   


在Java中将String设计成不可变的是综合考虑到各种因素的结果,想要理解这个问题,需要综合内存,同步,数据结构以及安全等方面的考虑. 在下文中,将为各种原因做一个小结。

官网:http://www.itxxz.com

1. 字符串常量池的需要 IT学习者(www.itxxz.com)

字符串常量池(String pool, String intern pool, String保留池) 是Java堆内存中一个特殊的存储区域, 当创建一个String对象时,假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。 copyright www.itxxz.com

如下面的代码所示,将会在堆内存中只创建一个实际String对象.
 

IT学习者(www.itxxz.com)

String string1 = "abcd";
String string2 = "abcd"; 
官网:http://www.itxxz.com

示意图如下所示:


  copyright www.itxxz.com

假若字符串对象允许改变,那么将会导致各种逻辑错误,比如改变一个对象会影响到另一个独立对象. 严格来说,这种常量池的思想,是一种优化手段. 本文来自www.itxxz.com

思考: 假若代码如下所示,s1和s2还会指向同一个实际的String对象吗?
  内容来自www.itxxz.com

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

本文来自www.itxxz.com


也许这个问题违反新手的直觉, 但是考虑到现代编译器会进行常规的优化, 所以他们都会指向常量池中的同一个对象. 或者,你可以用 jd-gui 之类的工具查看一下编译后的class文件.

本文来自www.itxxz.com

  copyright www.itxxz.com

2. 允许String对象缓存HashCode

Java中String对象的哈希码被频繁地使用, 比如在hashMap 等容器中。

本文来自www.itxxz.com

字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存.这也是一种性能优化手段,意味着不必每次都去计算新的哈希码. 在String类的定义中有如下代码:

IT学习者(www.itxxz.com)

 IT学习者(www.itxxz.com) 
private int hash;//this is used to cache hash code. 
copyright www.itxxz.com

3. 安全性

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

copyright www.itxxz.com

假如有如下的代码:
 

本文来自www.itxxz.com

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);
} itxxz.com 


英文标题:Why String is immutable in Java ? 官网:http://www.itxxz.com

原文翻译:www.itxxz.com 本文来自www.itxxz.com






文章除注明转载外,均为IT学习者原创或编译
欢迎任何形式的转载,但务必请以超链接形式注明出处
本文出自:IT学习者
链接地址:http://www.itxxz.com



微信公众号:喝咖啡的螃蟹

喝咖啡的螃蟹
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)