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

时间:2022-09-06 19:51:24
There are many reasons due to the string class has been made immutable in Java. These reasons in view, concurrency issues, security issues and performance issues. Here is a list of various valid reasons to go for immutable string class:

String在Java中被设计成不可变的是出于很多方面的考虑. 这么做主要是针对并发问题,安全问题和性能问题。下面列出了将String设计为不可变的各种原因:

同步

. The use of immutability is a best practice and has been recommended by many sources including effective Java and official Oracle Java tutorials. The property of the object is that none of the member variables that object can be changed as they are marked as private and final. This property becomes an advantage in case of multi-threaded applications. Since the updating of the String object is not allowed, multiple threads cannot run in to synchronization issues which occur when one object updates the state of object while the other was reading the object.

. “使用不可变的对象”是一个最佳实践,很多地方包括Effective Java(是一本书)和Oracle官方的教程都推荐使用这个准则. 不可变对象的所有成员变量都是不可变的,因为它们被设置成了private和final的. 在多线程环境中,这样的属性成了一个很大的优势. 由于对于String对象的修改操作是不允许的, 多线程环境中就不会遇到同步的麻烦,比如:一个线程正在更新数据而另一个线程正在读取数据.

The official Oracle Java tutorial says that developers should not have any doubt by using immutability. Usually developers think that by having immutability the number of objects in the memory will increase because instead of updating an object, a new object has to be created. But in reality this is balanced off by the reduction in garbage collector execution. If properly used immutability can make an application more stable.

Oracle的官方教程说:开发人员在使用不可变对象的时候不应该有任何疑虑.通常开发者们会认为内存中不可变对象的数量会越来越多因为对于一个对象的更改并不是真正的修改该对象,而是产生新的对象. But in reality this is balanced off by the reduction in garbage collector execution. 在程序中正确地使用不可变对象反而会使应用更加稳定。

性能

. The second reason why string class is immutable in Java is both a cause as well as effect of string being immutable. Strings in Java in implement the fly weight design pattern and the result is string literal pool. This literal pool has the property that if string literal is already present in the literal pool then it will be reused every-time a string reference variable is initialized to a string literal with the same characters.

.字符串不可变的第二个原因也可以理解为是字符串不可变的结果。Java中字符串实现的是享元模式,这就导致了字符串缓冲池的出现,字符串缓冲池的特点就是,如果一个字符串字面量已经在缓冲池中存在了,那么每次当一个字符串引用比那辆使用相同的字面值初始化的时候,这个字面量都将被重复使用。

The requirement for having a string literal pool arises from the fact that string class is immutable in Java. Imagine a scenario where millions of string objects have been created with same characters just because the new operator always creates and returns a new instance of the class and we cannot modify a string object once it has been created. The above scenario will result in performance issues. To avoid these performance issue, string literal pool has been introduced in Java.

字符串缓冲池的产生也是基于String在Java中是不可变的这个事实。假设一个场景:数十万计的具有相同字符的字符串对象被创建,而这仅仅是因为new操作符总是创建并返回一个新的字符串实例,而且创建后的每个字符串都不能被修改。这样的场景下将导致性能问题。为了避免这些性能问题,Java就引入了字符串缓冲池。

Now let us see why string literal pool is a cause for making string class immutable in Java. Since the string literals have to be reused, updating the contents of these objects should not be allowed. Had updating of string literals been allowed, a string literal may not be reused because its contents have been changed by another reference variable.

现在让我们看看为什么字符串缓冲池也是促使String被设计成不可变的原因。既然字符串字面量可以被重复使用,那么对于字符串的修改也就是不被允许的。如果对于字符串字面量的修改是被允许的,那么字符串将不能再被重用因为它的内容已经被其他引用变量修改过了。

性能

. The most used key object for hash map is the string object. Every time a string is referenced in hash based collections classes, it’s hash code is calculated. The hash code of string objects depends upon the characters contained in that string. If the characters of a string object were allowed to be changed, the hash code of that string object will change when the characters of the string change. By making string class immutable in Java, it has been insured that the hash code of string object will not change after the string object has been created in the memory. More over, this allows the hash code to be cached as a member variable. Once the hash code has been calculated for a string object and is told as the value of this internal member variable, the same can be returned next time without the need for performing any calculation.

.在哈希Map中使用最多的Key值就是字符串对象。每次当一个字符串被基于Hash算法的集合类所引用的时候,它的Hash值都将被计算出来。Hash值的结果取决于包含在字符串中的各个字符。如果字符串中的字符可以被改变,那么字符串的Hash值也将随着字符的改变而改变。通过将String设计成不可变的,就保证了当字符串在内存中被创建之后,它的hash值就不会发生改变。这样就使得Hash值可以被作为成员变量缓存起来,一旦一个字符串对象的Hash值被计算出来,而且被作为字符串的内部变量,那么下一次需要使用Hash值的时候就可以无需进行额外的计算就返回同样的值。

安全

. The security aspect of having the string class immutable in Java is that strings are used for file operations, memory management and network operations. If strings are allowed to be mutable, various properties could be changed in malicious ways.

.在安全方面将String设计成不可变的原因就是String被用来进行文件操作,内存管理和网络操作。如果字符串可以被修改,那么很多属性都将可能被恶意修改。

简单

. Another reason to make the string class mutable is the simplicity aspect. Though for beginners it is a learning curve to understand the behavior of string objects but once they understand, it is very easy to visualize the behavior of string objects in any particular scenario. Allowing the updating of string objects would have made it more complex to understand the behavior of strings.

.另一个将String设计成不可变的原因就是出于简单方面的考虑。尽管对于初学者来说理解字符串对象的行为是比较有难度的,但一旦他们理解了,在任何特殊的场景下理解字符串对象的行为就变得很容易了。而将字符串设计成可变的将使得这个理解的过程更加复杂。

The point to note about the design decision is that the advantages of making string class immutable are more than not making it immutable.

注意:这样设计的原因就是String不可变比String可变具有更多的优势。

========个人总结=========

之所以将String设计成为Immutable的,这是由String的作用所决定的。

1.这样可以解决同步安全问题。

2.设计成不可变的就会导致性能下降,因为每次修改都将产生新的对象,而字符串缓冲池很好的解决了这个问题。

3.安全,因为很多操作都是以字符串作为参数的,字符串如果可以修改,那么在我们操作的过程中如果有人对字符串进行了修改,那么我们将得不到正确的结果。

参考资料:

(1)http://www.javaexperience.com/why-the-string-class-is-immutable/#ixzz2grdKUGIh

(2)http://javarevisited.blogspot.com/2010/10/why-string-is-immutable-in-java.html

为什么Java中的String是设计成不可变的?(Why String is immutable in java)的更多相关文章

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

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

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

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

  3. 为什么String要设计成不可变的?

    英文原:http://www.programcreek.com/2013/04/why-string-is-immutable-in-java/ 转自:http://blog.csdn.net/ren ...

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

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

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

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

  6. 图说:为什么Java中的字符串被定义为不可变的

    8张图,看懂Java字符串的不变性 字符串,想必大家最熟悉不过了,通常我们在代码中有几种方式可以创建字符串,比如:String s = "Hollis";这时,其实会在堆内存中创建 ...

  7. java中如何把图片转换成二进制流的代码

    在学习期间,把开发过程经常用到的一些代码段做个备份,下边代码内容是关于java中如何把图片转换成二进制流的代码,应该能对各朋友也有用处. public byte[] SetImageToByteArr ...

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

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

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

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

随机推荐

  1. HTML DOM基础知识

    HTML DOM基础知识 一.什么是DOM? 1.HTML DOM 定义了访问和操作HTML文档的标准方法. 2.HTML DOM 把 HTML 文档呈现为带有元素.属性和文本的树结构(节点树). 3 ...

  2. hdu City Game

    做这题之前建议做一下hdu1506题,两道题是极度相似的题,不同的是这个要处理的是m行,所以可以用一个dp[][]数组存储矩形的高度,之后就变成hdu1506了. 例如测试样例: 0 1 1 1 1 ...

  3. JPA学习---第四节:JPA实例与JPA主键生成策略

    1.编写实体类,代码如下: package learn.jpa.bean; import javax.persistence.Entity; import javax.persistence.Gene ...

  4. Wcf 文件上传下载

    wcf 文件上传的例子网上很多,我也是借鉴别人的示例.wcf 文件下载的示例网上就很少了,不知道是不是因为两者的处理方式比较类似,别人就没有再上传了.在此本人做下记录备忘. UploadFile.sv ...

  5. CVE-2015-0057 POC构造 & 利用分析(2015.7)

    CVE-2015-0057 POC构造 & 利用分析 主要内容: 构造POC 利用思路 0x00 初探 从这篇文章可以获知: 1.问题出在 win32k!xxxEnableWndSBArrow ...

  6. MPlayerX播放视频屏幕中间有图标遮挡的解决办法

    问题如下: 解决办法: 在应用程序文件夹中找到MPlayerX,鼠标右击应用图标,在右键菜单中选择"显示包内容",进入如下目录:Contents->Resources,找到l ...

  7. IDEA集成SSH Session

    1,在菜单栏选择Tools -> Start SSH Session 2,在SSH Session表单中输入: 3,在IDEA下方会弹出Terminal控制台,直接敲命令即可.  ------- ...

  8. Linux下GoAccess的安装与全部用法

      GoAccess用户文档 一. GoAccess概述 1.1 GoAccess概述 goaccess是一个实时的web日志分析器,以及交互式查看器,在类Unix系统的终端(terminal)上运行 ...

  9. 机器学习Hands On Lab

    fetch_data fetch_mldata默认路径是在scikit_learn_data路径下,mnist的mat文件其实直接放置到scikit_lean/mldata下面即可通过fetch_ml ...

  10. [吴恩达机器学习笔记]13聚类K-means

    13.聚类 觉得有用的话,欢迎一起讨论相互学习~Follow Me 13.1无监督学习简介 从监督学习到无监督学习 在一个典型的监督学习中,我们有一个有标签的训练集,我们的目标是找到能够区分正样本和负 ...