Java-Basics-Strings-为什么Java中的字符串是不可变的?
2013-12-16 16:11
281 查看
字符串String在Java中被设计成不可变是有多个原因的。
如果字符串不是不可变的话(双重否定句,表示字符串可变),那么使用一个reference(比如str1)改变了字符串的值的话就会使其他reference所指向的字符串内容的变化。(对字符串的改变操作都会返回一个新的字符串,详细内容请见这里 )
在String类中,有以下代码:
以下是一个例子:
最后总结,Java中String被设计成不可变的原因包括了设计、效率和安全性。
1. 字符串池(String Pool)的需求
字符串池(String intern pool)在方法区域中是一个特殊的存储区域。如果某字符串已经存在于字符串池中了,那么当创建同样内容的字符串时,就会返回该字符串的reference,而不会重新创建一个新的object。下面两行代码创建的字符串只会在内存的heap中创建一个字符串objectString str1 = "abcd"; String str2 = "abcd";用一张图来形象地表示就是这样的:
如果字符串不是不可变的话(双重否定句,表示字符串可变),那么使用一个reference(比如str1)改变了字符串的值的话就会使其他reference所指向的字符串内容的变化。(对字符串的改变操作都会返回一个新的字符串,详细内容请见这里 )
2. 允许String缓存其哈希值
Java中会频繁使用字符串的哈希值。比如说HashMap。字符串的不可变性保证了哈希值一定是不变的,因此对哈希值进行缓存就不用担心其变化了。也就是说我们不需要在每次使用字符串的时候都去计算哈希值,这样带来的好处就是更加高效了在String类中,有以下代码:
private int hash; //this is used to cache hash code.
3. 安全性
String在许多java类中广泛用于参数存在,比如网络连接、打开的文件等等。如果String不是不可变的,连接connection或文件file就可能被改变,从而导致严重的安全问题。方法method认为其连接的是一台机器,但实际上却不是。在反射Relection中可变的字符串也会导致安全问题,因为参数都是字符串类型的。以下是一个例子:
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); }
最后总结,Java中String被设计成不可变的原因包括了设计、效率和安全性。
相关文章推荐
- 为什么Java中的字符串是不可变的?
- 为什么Java中字符串是不可变的
- [图说Java](2)Java中字符串为什么是不可变的
- 为什么Java要把字符串设计成不可变的
- 身为大神的你知道为什么Java要把字符串设计成不可变的嘛!
- 首页所有文章资讯Web架构基础技术书籍教程我要投稿更多频道 » 为什么Java要把字符串设计成不可变的
- 为什么Java中字符串被设计成不可变的?
- 图说:为什么Java中的字符串被定义为不可变的
- 为什么Java要把字符串设计成不可变的
- 为什么Java要把字符串设计成不可变的
- 为什么Java中的字符串被定义为不可变的
- 为什么要把Java字符串设计为不可变的
- 为什么Java中的字符串被定义为不可变的
- 为什么Java要把字符串设计成不可变的
- 【String】为什么 Java 要把字符串设计成不可变的
- 为什么 Java 要把字符串设计成不可变的
- 为什么Java要把字符串设计成不可变的
- 为什么Java要把字符串设计成不可变的
- 为什么 Java 要把字符串设计成不可变的
- Java-Basics-Strings-字符串在Java中是通过“引用”传递的吗?