请选择 进入手机版 | 继续访问电脑版

HTML5星空

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

[复制链接]
发表于 2017-7-29 00:10:34 | 显示全部楼层 |阅读模式

尚学堂导读
 

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


1
字符串常量池的需要

字符串常量池( String pool, String intern pool, String 保留池)


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


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


String string1 = "abcd";

String string2 = "abcd";



示意图如下所示:

假若字符串对象允许改变,那么将会导致各种逻辑错误,比如改变一个对象会影响到另一个独立对象。


严格来说,这种常量池的思想,是一种优化手段。

请思考:假若代码如下所示,s1 和 s2 还会指向同一个实际的 String 对象吗?


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


也许这个问题违反新手的直觉,但是考虑到现代编译器会进行常规的优化,所以他们都会指向常量池中的同一个对象。


或者,你可以用 jd-gui 之类的工具查看一下编译后的 class 文件。


2
允许 String 对象缓存 HashCode

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


字符串不变性保证了 hash 码的唯一性,因此可以放心地进行缓存。


这也是一种性能优化手段,意味着不必每次都去计算新的哈希码.。

在 String 类的定义中有如下代码:


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


3
安全性

String 被许多的 Java 类(库)用来当做参数。


例如:网络连接地址URL,文件路径path,还有反射机制所需要的 String 参数等,。

假如 String 不是固定不变的,将会引起各种安全隐患。


假如有如下的代码:


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年内,软件工程师行业将成为最受欢迎的10大行业之一,而且市场需求很大。


只要努力学习,就一定能在本行业取得一番成就。


信任是最伟大的力量,我们不但信任软件行开发业的职业前景,更加信任西安尚学堂学员们的实力,相信他们都是未来最闪耀的软件工程师。


尚学堂--8月开班时间

Java--零基础入门就业班


开课时间:2017年07月08日、8月15日、8月22日   抢座中..


电话:029-62258374  

地址:陕西省西安市高新区科技二路西安软件园天泽大厦五楼


免费公开课

每周二、四、六

周二周四公开课下午两点开始

周六公开课早上九点开始

在公众号主页发送【试听】获取免费听课名额


尚学堂Java培训


海量 IT 编程资料供您享用





点击下方"阅读原文"获取免费听课名额

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快讯
发布主题 快速回复 返回列表

     京ICP备14042305号

html5star team © 2012-2013 html5星空 Comsenz Inc.

GMT+8, 2019-5-26 09:37 , Processed in 0.204374 second(s), 36 queries .

快速回复 返回顶部 返回列表