Java-Basics-Strings-为什么Java中的字符串是不可变的?

来源:互联网 发布:蓝鸟编程使用教程 编辑:程序博客网 时间:2024/05/01 22:40

         字符串String在Java中被设计成不可变是有多个原因的。

1. 字符串池(String Pool)的需求

         字符串池(String intern pool)在方法区域中是一个特殊的存储区域。如果某字符串已经存在于字符串池中了,那么当创建同样内容的字符串时,就会返回该字符串的reference,而不会重新创建一个新的object。下面两行代码创建的字符串只会在内存的heap中创建一个字符串object

String str1 = "abcd";String str2 = "abcd";
用一张图来形象地表示就是这样的:

java-string-pool

如果字符串不是不可变的话(双重否定句,表示字符串可变),那么使用一个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被设计成不可变的原因包括了设计、效率和安全性。

0 0
原创粉丝点击