String类是Java中的一个不可变类(immutable class)。

简单来说,不可变类就是实例在被创建之后不可修改。

在《Effective Java》 Item 15 中提到了为了使类成为不可变,需要遵循的五条规则:

  1. 不要提供任何会修改对象状态的方法。

  2. 保证类不会被扩展。

  3. 使所有的域都是final的。

  4. 使所有域都成为私有的。

  5. 确保对于任何可变组件的互斥访问。

不可变类有许多优点,不可变类比可变类更加易于设计、实现和使用,不容易出错,且更加安全。

下面来看一下Java把String类设计为不可变类的几个原因:

1. 由于字符串池的存在

字符串池(String Pool)是方法区中的一块存储空间,当创建一个字符串时,如果池中已经存在相同的字符串就会返回其引用,而不是在堆中创建一个新对象。(此处指的是字面量创建字符串,用new关键字创建的话,无论池中存不存在都会在堆中创建一个新对象)

String string1 = "abcd";
String string2 = "abcd";

如果字符串是可变的话,通过一个引用改变它的值,将会导致其他引用的值也同样改变,从而可能发生错误。

2. 缓存hashcode

Java中经常用到一个字符串的hashcode,例如在HashMap和HashSet中。不可变性保证同一个字符串对象的hashcode总是相同的,而在使用时不用考虑其是否发生改变。

这意味着不需要每次都计算一遍hashcode,使程序更加高效。

/** Cache the hash code for the string */
private int hash; // Default to 0
3. 保证其他对象的使用

为了具体一点,举一个栗子。

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

在这个例子中,如果String是可变的话将破坏HashSet(集合中可能会包含重复元素)。

4. 安全性

在Java中String被用作许多方法的参数,例如网络连接,对文件的操作等等。

假如String不是不可变的,一个连接或文件将可能被改变,这会产生严重的安全隐患。

因为Java中反射的参数也是字符串,所以可变字符串同样会产生安全问题。

下面是一个例子:

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. 不可变对象自然是线程安全的

不可变对象是线程安全的,它们可以被自由地共享,不要求同步。

不可变类的优势有很多,当然也有缺点,就是对于每个不同的值都需要一个单独的对象。


转载请注明原文链接:http://www.cnblogs.com/justcooooode/p/7514863.html

参考资料

《Effective Java》Item 15

https://www.programcreek.com/2013/04/why-string-is-immutable-in-java/

为什么Java中的String类是不可变的?的更多相关文章

  1. Java中的String为什么是不可变的?

    转载:http://blog.csdn.net/zhangjg_blog/article/details/18319521 什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那 ...

  2. Java基础知识强化101:Java 中的 String对象真的不可变吗 ?

    1. 什么是不可变对象?       众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对 ...

  3. Java中的String为什么是不可变的? -- String源码分析

    众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的.不能改变状态的意思是, ...

  4. Java中的String为什么是不可变的? — String源码分析

    原文地址:http://www.importnew.com/16817.html 什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为 ...

  5. 【转】Java中的String为什么是不可变的? -- String源码分析

    什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的.不 ...

  6. (转)Java中的String为什么是不可变的? -- String源码分析

    背景:被问到很基础的知识点  string  自己答的很模糊 Java中的String为什么是不可变的? -- String源码分析 ps:最好去阅读原文 Java中的String为什么是不可变的 什 ...

  7. 关于Java中的String类知识点小总结

    Java中的String类知识点 前言 在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 如何创建字符串 最简单的方式 String str = "he ...

  8. Java 中的 String 真的是不可变吗?

    我们都知道 Java 中的 String 类的设计是不可变的,来看下 String 类的源码. public final class String implements java.io.Seriali ...

  9. JAVA中的String类(详解)

    Java.lang.String类是final类型的,因此不可以继承这个类.不能修改这个类.String是一个类不属于基本数据类型. 可以从源码中看到,String是一个final类型. String ...

随机推荐

  1. 新博客在SEO方面需要注意哪几点?

    无论是什么程序的博客,都应该注意这重要的几点! 第一点:网站目标明确进入主题,有些人对于SEO不是特别熟悉,或者说没有接触过.当你做好一个网站,不管网站内容是什么,首先你都得了解最基本的SEO,比如网 ...

  2. LaTeX的表格插入与排版

    关于LaTex中的图表问题的几篇有用的文章 Graphics and Colour with LaTeX  有关在LaTex中插图和使用颜色的在线指导. Figure'ing and Picture' ...

  3. redi安装

    借鉴文章:https://segmentfault.com/a/1190000010709337 在linux中使用wget时,若报-bash: wget: command not found,则表明 ...

  4. JAVA中反射机制五(java.lang.reflect包)

    一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段, ...

  5. Java基础---继承、抽象、接口

    一.概述         继承是面向对象的一个重要特征.当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可.这时,多个类可以称为子类,单 ...

  6. jmeter系列-------注意事项

    1.自己创建的数据自己擅长,不要留垃圾数据 2.每个接口都需要增加断言,保证脚本的结果的正确性 3.相同的应用放在一个简单控制器下,所有的应用尽量放在一个线程组下面,将特殊场景单独抽离成一个线程组 4 ...

  7. eval浅解

    关于eval,你了解多少呢?来看看 eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码. 需要一个参数(string),切必需.要计算的字符串,其中含有要计算的 JavaS ...

  8. Color.js增强你对颜色的控制

    往逝之因 不要低头,皇冠会掉...  可你又没有皇冠 Color.js 增强你对颜色的控制 阅读目录 轻松管理颜色--color.js库 使用color.js Accessor Methods 你该知 ...

  9. 图论中DFS与BFS的区别、用法、详解?

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

  10. (转)C语言malloc()与free()的使用

    如何使用 malloc 函数 本文为转载内容,原文地址请点击 不要莫名其妙,其实上面这段小小的对话,就是malloc的使用过程.malloc是一个函数,专门用来从堆上分配内存.使用malloc函数需要 ...