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

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

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

1. 字符串常量池的需要

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

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

[java] view
plain
copy

  1. String s1 = "abcd";
  2. String s2 = "abcd";

示意图如下所示:

图1

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

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

[javascript] view
plain
copy

  1. String s1= "ab" + "cd";
  2. String s2= "abc" + "d";

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

2. 允许String对象缓存HashCode

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

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

[javascript] view
plain
copy

  1. private int hash;//用来缓存HashCode

3. 安全性

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

假如有如下的代码:

[javascript] view
plain
copy

  1. boolean connect(string s){
  2. if (!isSecure(s)) {
  3. throw new SecurityException();
  4. }
  5. // 如果在其他地方可以修改String,那么此处就会引起各种预料不到的问题/错误
  6. causeProblem(s);
  7. }

总体来说, String不可变的原因包括 设计考虑,效率优化问题,以及安全性这三大方面. 事实上,这也是Java面试中的许多 "为什么" 的答案。

为什么String要设计成不可变的?的更多相关文章

  1. String的内存模型,为什么String被设计成不可变的

    String是Java中最常用的类,是不可变的(Immutable), 那么String是如何实现Immutable呢,String为什么要设计成不可变呢? 前言 关于String,收集一波基础,来源 ...

  2. 为什么Java中的String是设计成不可变的?(Why String is immutable in java)

    There are many reasons due to the string class has been made immutable in Java. These reasons in vie ...

  3. 深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因

    声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/det ...

  4. String被设计成不可变和不能被继承的原因

    String是所有语言中最常用的一个类.我们知道在Java中,String是不可变的.final的.Java在运行时也保存了一个字符串池(String pool),这使得String成为了一个特别的类 ...

  5. String类为什么设计成不可变的

    在Java中将String设计成不可变的是综合考虑到各种因素的结果,需要综合考虑内存.同步.数据结构以安全方面的考虑. String被设计成不可变的主要目的是为了安全和高效. 1)字符串常量池的需要 ...

  6. String类为什么被设计成不可变类

    1.享元模式: 1.共享元素模式,也就是说:一个系统中如果有多处用到了相同的一个元素,那么我们应该只存储一份此元素,而让所有地方都引用这一个元素. 2.Java中String就是根据享元模式设计的,而 ...

  7. [2017-09-04]Abp系列——为什么值对象必须设计成不可变的

    本系列目录:Abp介绍和经验分享-目录 这篇是之前翻备忘录发现漏了的,前阵子刚好同事又提及过这个问题,这里补上. 本文重点在于理解什么是值对象的不可变性. Abp的ValueObject以及EF的Co ...

  8. 为什么String被设计为不可变?是否真的不可变?

    1 对象不可变定义 不可变对象是指对象的状态在被初始化以后,在整个对象的生命周期内,不可改变. 2 如何不可变 通常情况下,在java中通过以下步骤实现不可变 对于属性不提供设值方法 所有的属性定义为 ...

  9. Java为什么把String设计成不可变的(immutable)

    在java中,String是字符串常量,可以从内存,同步机制,数据结构等方面分析 1:字符串中常量池的需要 String不同于普通基础变量类型的地方在于对象.java中的字符串对象都保存在字符串常量池 ...

随机推荐

  1. PHP 冒泡排序法

    <?php // 冒泡排序法:将一个数组中的值按照从小到大的顺 序排序 $arr = array(33, 1, 4, 5, 2, 3, 7, 9, 8, 99); $len = count($a ...

  2. Adding the Test API in The ASP.NET Web API Help Page

    1.通过NuGet引用Web API Test Client 引用玩该DLL会生成如下文件: 这里面就是我们的帮助文档界面 2.在项目属性中进行如下设置,勾选XMl文档文件,并设置路径 3.在项目的A ...

  3. POJ 3273 Monthly Expense 二分枚举

    题目:http://poj.org/problem?id=3273 二分枚举,据说是经典题,看了题解才做的,暂时还没有完全理解.. #include <stdio.h> #include ...

  4. 使用ajax和history.pushState无刷新改变页面URL onpopstate(转)

    Javascript代码 var htmlData1 = $.ajax(    {    url: "/getXXXResponse",    async: false }).re ...

  5. bzoj3677: [Apio2014]连珠线

    Description 在列奥纳多·达·芬奇时期,有一个流行的童年游戏,叫做“连珠线”.不出所料,玩这个游戏只需要珠子和线,珠子从1到礼编号,线分为红色和蓝色.游戏 开始时,只有1个珠子,而接下来新的 ...

  6. 百度预测 及 maven pom搜索地址

    http://trends.baidu.com/ http://mvnrepository.com/artifact/net.sourceforge.htmlcleaner/htmlcleaner/2 ...

  7. uva 1267 - Network

    这个题目关键在于把无根树变成有根树:这个用dfs: 然后用贪心的方法,从最深的那层开始,每次找到节点的上k层,建一个服务器,然后用一个dfs把这个服务器能够覆盖的节点标记: #include<c ...

  8. Server-Side Access Control

    Firefox 3.5 implements the W3C Access Control specification.  As a result, Firefox 3.5 sends specifi ...

  9. weixin

    http://gps.yesky.com/19/34467019.shtml http://***/goods.php?id=320 http://www.sablog.net/blog/archiv ...

  10. 使用jdk生成证书以及把证书导入到jdk中

    证书对于实现此单点登录非常之重要,证书是服务器端和客户端安全通信的凭证,本教程只是演示,所有用了JDK自带的证书生成工具keytool.当然在实际项目中你可以到专门的证书认证中心购买证书. 中文官方网 ...