• 欢迎访问天天编码网站,Java技术、技术书单、开发工具,欢迎加入天天编码
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏天天编码吧
  • 我们的淘宝店铺已经开张了哦,传送门:https://shop145764801.taobao.com/

为什么Java中String类是不可变的

Java基础 tiantian 2368次浏览 0个评论 扫描二维码

在Java中,String是一个 不可变(immutable) 的类。Java中的不可变类的含义是指该类的实例对象不能被修改,是一个常量对象。在实例对象被创建的时候,对象内部所需的所有信息就已经全部初始化好了,所有的这些信息都不能后期修改了。相对于普通类,不可变类具有非常多的优势。本文就是要重点学习String类的不可变特性,同时总结一下为什么Java中的String类要设计成不可变类。当然,这需要我们对Java中的JVM内存模型、同步机制、数据结构等知识有一定的理解。

不可变特性

首先,我们直接看一下如下的代码片段:

String strA = "www.tiantianbianma.com";

这段代码的JVM内存布局简图如下:

为什么Java中String类是不可变的

接着,我们再加入一行代码,变成如下所示:

String strA = "www.tiantianbianma.com";
String strB = strA.concat("/java");

这段代码的JVM内存布局简图变成如下所示:

为什么Java中String类是不可变的

可以发现,String对象一旦创建完成,就不可再被修改了。不仅是concat方法,String类中的所有方法都无法修改String对象本身,而是返回一个新的String对象。

设计理由

String类被设计成为一个不可变类,背后有什么原因和理由呢?本文在网络资料的基础之上,总结出如下几点。

String常量池需要

正如我们所知,String常量池是JVM内存模型中方法区的一个特殊区域,用于存储String常量。当我们使用 字符序列 方法创建String对象,且该字符序列对象已经存在于String常量池时,此次不会真的创建新的String对象,而是返回了原来对象。

我们还是直接通过代码示例来理解:

String strA = "www.tiantianbianma.com";
String strB = "www.tiantianbianma.com";

上述的代码片段对于的JVM内存布局简图如下:

为什么Java中String类是不可变的

如果String是可变类,一个引用(strA)对String对象的修改,导致另一个引用(strB)获取了错误的值。

缓存HashCode

String的hashcode在java程序中被使用的频率非常之高,特别是String经常作为HashMap、HashTable等数据结构的key。String作为一个不可变类,其对象的hashcode值就不会发生变化,所以可以把String对象的hashcode值缓存起来,避免了每次的重新计算成本,这可以提升程序的性能。在String类的源码中,我们可以发现如下的代码片段:

private int hash;//this is used to cache hash code.

安全

Java中的许多类广泛地使用String作为参数类型,比如网络连接、文件操作等。如果String类是可变的,网络连接或者文件指针就有可能被有意地或无意地篡改,从而导致严重的安全威胁。程序原本以为自己链接到了一台指定的机器,实际情况却不是。Java依赖反射机制实现语言的动态特性,如果String类是可变的且是反射方法的参数类型,反射特性就会有严重的安全问题。

线程安全

不可变类的对象天生就是的多线程安全的,多线程能力对于Java这门全球用户最多的语言是非常重要的。因为不可变类的对象不可被修改,所以它们可以被多个线程之间安全地共享。这样就不需要复杂和损耗性能的同步机制了。

总结

Java把对于字符串类型的String类设计为不可变类,好处是显而易见的。本文也试图从多个维度去理解其带来的优势。但是,String类的不可变特性也有一个缺点:对于Java程序中常见的大量字符串拼接功能会带来极大的性能损耗。针对于此,建议使用StringBuffer或者StringBuilder类来完成此功能。实际上,Java编译器往往会自动完成这样的优化。


天天编码 , 版权所有丨本文标题:为什么Java中String类是不可变的
转载请保留页面地址:http://www.tiantianbianma.com/java-string-immutablity.html/
喜欢 (11)
支付宝[多谢打赏]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址