为什么Java要把字符串设计成不可变的
来源:原创 时间:2017-05-17 浏览:5141 次String是Java中一个不可变的类,所以他一旦被实例化就无法被修正。不可变类的实例一旦创立,其成员变量的值就不能被修正。不可变类有许多优势。这篇文章总结了为何字符串被规划成不可变的。将涉及到内存、同步和数据结构有关的常识。
字符串池
字符串池是办法区中的一部分特别存储。当一个字符串被被创立的时分,首要会去这个字符串池中查找,假如找到,直接回来对该字符串的引证。
下面的代码只会在堆中创立一个字符串
下面是图示:
假如字符串可变的话,当两个引证指向指向同一个字符串时,对其间一个做修正就会影响别的一个。(请记住该影响,有助于了解后边的内容)
缓存Hashcode
Java中经常会用到字符串的哈希码(hashcode)。例如,在HashMap中,字符串的不可变能保证其hashcode永久保持一致,这么就能够防止一些不必要的费事。这也就意味着每次在运用一个字符串的hashcode的时分不必从头核算一次,这么愈加高效。
在String类中,有以下代码:
以上代码中hash变量中就保留了一个String目标的hashcode,由于String类不可变,所以一旦目标被创立,该hash值也无法改动。所以,每次想要运用该目标的hashcode的时分,直接回来即可。
使别的类的运用愈加便当
在介绍这个内容之前,先看以下代码:
在上面的比方中,假如字符串能够被改动,那么以上用法将有也许违背Set的规划准则,由于Set请求其间的元素不能够重复。上面的代码仅仅为了简略阐明该疑问,本来String类中并没有value这个字段值。
安全性
String被广泛的运用在别的Java类中充任参数。比方网络衔接、翻开文件等操作。假如字符串可变,那么相似操作也许致使安全疑问。由于某个办法在调用衔接操作的时分,他以为会衔接到某台机器,可是实际上并没有(别的引证同一String目标的值修正会致使该衔接中的字符串内容被修正)。可变的字符串也也许致使反射的安全疑问,由于他的参数也是字符串。
代码示例:
不可变目标天然生成即是线程安全的
由于不可变目标不能被改动,所以他们能够自由地在多个线程之间同享。不需要任何同步处理。
总归,String被规划成不可变的首要意图是为了安全和高效。所以,使String是一个不可变类是一个极好的规划。
纳尼?怎样就没有了呢?是不是意犹未尽?