Java为什么把String设计成不可变的?
来源:互联网 发布:艾媒咨询知乎 编辑:程序博客网 时间:2024/05/22 08:15
原文来自:Why String is immutable in Java?
这是来自Java和Android面试中经常被问的一道题目。在Java语言中,String是字符串常量,StringBuilder是字符串变量,为什么将String设计成不可变的(immutable)?
在Java里String类是不可变的,不可变类是一个不能被修改实例的类,实例创建时所有的信息都被初始化,并且不可被修改。这样的设计也有很多优点,本文从内存、同步和数据结构方面总结了为什么把String类设计成不可变的原因。
1、字符串常量池的需要
字符串常量池是一个特殊的存储区域。当创建字符串时,如果字符串已经存在于池中,则将返回现有字符串的引用,而不会创建新的对象。
下面的代码只在堆中创建一个字符串对象:
String string1 = "abcd";String string2 = "abcd";
示意图如下:
如果String是可变的,用一个引用改变字符串将导致其他引用的值错误。
2、HashCode缓存
在Java里存储一个字符串通常需要使用到HashCode值,例如,在一个HashMap或一个HashSet。一成不变可以保证HashCode的唯一性,不用考虑他的变化。这意味着不需要每次使用它的时候都计算HashCode,提高操作效率。
在String类中有如下代码:
private int hash;//this is used to cache hash code.
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";
在这个实例中,如果字符串是可变的,他将违背集合的设计(集合包含非重复元素)。当然,上面的示例仅仅用作演示用,在真正的字符串类中没有值字段。
4、安全
字符串被广泛用于许多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、不可变对象自然是线程安全的
因为不可变对象是不能被改变的,所以他们可以自由的共享多线程。这就消除了他们进行同步的要求。
总结
总之,String被设计成不可变的是出于效率和安全的因素。这也是为什么很多情况下首选类是不可变类的原因。
当然,不同的使用场景体现出不可变特性的优势也不相同。大家可以回忆自己项目中的使用场景,多加思考这类问题。
- Java为什么把String设计成不可变的?
- 【String】为什么 Java 要把字符串设计成不可变的
- 为什么Java要把字符串设计成不可变的
- 为什么Java要把字符串设计成不可变的
- 为什么 Java 要把字符串设计成不可变的
- 为什么 Java 要把字符串设计成不可变的
- 为什么Java要把字符串设计成不可变的
- 为什么Java要把字符串设计成不可变的
- 为什么Java中的String设计成不可变的?
- 为什么把String设计成不可变对象
- 为什么要把Java字符串设计为不可变的
- 为什么Java的String设计为不可变的?
- 身为大神的你知道为什么Java要把字符串设计成不可变的嘛!
- 为什么String要设计成不可变的?
- 为什么String要设计成不可变的?
- 为什么String要设计成不可变的?
- 为什么String要设计成不可变的?
- 为什么String要设计成不可变的?
- 解决问题 “You don't have permission to access /index.html on this server.”
- jquery 选择器的使用
- log4j2示例
- Oracle热备-自动化批处理文件
- 图论+前缀和 任(duty)
- Java为什么把String设计成不可变的?
- 类的定义之课堂练习1
- Bagging与随机森林
- Dubbo配置以及使用总结2
- 购买保健品被骗,如何才能识破保健品消费陷阱呢?
- JAVA基础--内部类
- java的栈,堆,静态区的理解
- MvvmLight中的Messenger详解
- bootstrap打开模态modal窗口引起页面抖动解决办法