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. String类为什么被设计成不可变类

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

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

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

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

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

随机推荐

  1. 转:CSS盒模型

    W3C 组织建议把所有网页上的对像都放在一个盒(box)中,设计师可以通过创建定义来控制这个盒的属性,这些对像包括段落.列表.标题.图片以及层.盒模型主 要定义四个区域:内容(content).边框距 ...

  2. IK 用java 代码实现分词

    需要导入IK 对应的jar 包 IKAnalyzer2012.jar lucene-core-4.10.jar public static void main(String[] args) throw ...

  3. asp.net core2.0 依赖注入 AddTransient与AddScoped的区别 - 晓剑 - CSDN博客

    原文:asp.net core2.0 依赖注入 AddTransient与AddScoped的区别 - 晓剑 - CSDN博客 原文地址:http://www.tnblog.net/aojiancc2 ...

  4. D3.js的基础部分之数组的处理 集合(Set)(v3版本)

    数组的处理 之 集合(set) 集合(Set)是数学中常用的概念,表示具有某种特定性质的事物的总体.集合里的项叫做元素.集合的相关方法有:   d3.set([array]) //使用数组来构建集合, ...

  5. 21-1字符串相关api

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 用js判断是否是微信浏览器

      //判断是否是微信浏览器的函数 function isWeiXin(){ //window.navigator.userAgent属性包含了浏览器类型.版本.操作系统类型.浏览器引擎类型等信息,这 ...

  7. iOS开发系列-Category

    Category Category是OC中特有的语法.Category的作用 * 可以在不修改原来类的基础上,为这个类扩充一些方法 * 一个庞大的类可以分为多个模块开发 * 一个庞大的类可以由多个人来 ...

  8. Spring注解基础学习总结

    1.依赖注入注解: @Component:Bean注入到Spring容器组件(通用) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE):Bean作用域( ...

  9. jquery无缝向上滚动实现代

    <!DOCTYPE html><html><head><style type="text/css">.renav{width:200 ...

  10. Android开发 自定义View_白色圆型涟漪动画View

    代码: import android.animation.ValueAnimator; import android.content.Context; import android.graphics. ...