1.3.为什么String在Java中是不可变

String在Java中是个不可更改的类。一个不可更改的类简单来说就是这个类的所有实例是不可以更改的。所有的实例信息在创建的时候被初始化而且信息是不可以更改的。不可更改的类有很多好处。
这篇文章总结了为什么String被设计成不可以改变的。一个好的回答需要深入理解内存、同步和数据结构等。

字符串池的需要

字符串池(字符串内部池) 是在方法区域的特殊区域。当一个string被创建如果这个string已经在内存里面存在了,那个存在的string的引用被返回,而不是创建个新的对象和返回它的引用。
下面的代码将在堆上创建一个string对象。
String string1 = "abcd"; String string2 = "abcd";

堆上创建String

如果这个string是可以改变的,通过一个引用改变一个string将导致另一引用指向错误的值。

缓存哈希值

在Java中,string的哈希值经常被用。举个例子,在HashMap中。保持不变,可以保证总是返回相同的哈希值。所以它可以被缓存而不用担心被改变。 这意味这不需要在使用的时候每次都计算哈希值。这将更高效。
在String类中,它有以下的代码:
private int hash;//this is used to cache hash code.

使其他类的使用更加容易。

为了更具体,想想下面的程序:

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是可以改变的,如果它的值被改变这将违反了Set的设计(Set不可以包含重复的元素)。这个例子是为了简化设计的,在实际的String类中没有value 属性。

安全

String 在很多java的类中,网络连接中,打开的文件中经常被作为参数使用。如果String是可以改变的,一个连接或者文件将有可能被改变,这将导致严肃的安全威胁。这个方法认为它正连接到一个机器,但是实际上不是。易变的strings将在反射或者作为参数将导致安全问题。
下面是代码实例:
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);
}

不变对象是自然线程安全

因为不可变对象是不可以改变的,它能够被多个线程自由的共享。这消除了同步。

总结

String被设计成不可以更改的是为了效率和安全。这也是为什么现在有很多不可以改变的类。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,281评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 33,775评论 18 399
  • 第一种模式:js工厂模式 #######工厂模式说明:1.在函数中定义对象,并定义此对象的各种属性,建议将为方法的...
    adtk阅读 3,590评论 0 1
  • 如何不用酵母做披萨 有一种又快又简单的方法,让你在不需要添加酵母的情况下做出好吃的披萨。如果你酵母过敏或者没有时间...
    大怪熊阅读 5,219评论 0 0
  • 一不小心,就成了一个爱哭鬼,但是只有自己才知道,眼泪藏在了风雪里。 太多时候,我们就是这样,无处可去,无人可知,无...
    隔壁住着动感超人阅读 3,950评论 0 3

友情链接更多精彩内容