java里面string用不了_浅谈为什么Java里面String类是不可变的

在Java里面String类型是不可变对象,这一点毫无疑问,那么为什么Java语言的设计者要把String类型设计成不可变对象呢?这是一个值得思考的问题

Java语言的创建者James Gosling,曾经在一次采访中被人问到:什么时候应该使用不可变对象(immutable object),他回答:任何可以使用的时候都会使用。

在这之前,我们先来简单了解一下,什么是不可变对象?

不可变对象指的是在对象创建之后,对象的内部状态以及对象的内存指针地址都不不能被改变。在Java里面final关键字就是用来辅助创建不可变对象的,但需要注意的是,对于基本类型被final修饰后,就彻底变成了不可变对象,而引用类型被final修饰后,仅仅是指针的内存地址不能改变,如果想要变成彻底的不可变类型,要把该对象里面所有的字段都得用final声明,包括嵌套的对象,否则对象的内部状态也是会变化的,这一点需要理解。

ok,下面我们来分析下为什么String是不可变的?

通过String源码可以看到,String类型的底层是由final修饰的char数组存储。

public final class String

implements java.io.Serializable, Comparable, CharSequence {

/** The value is used for character storage. */

private final char value[];

........

}

String能被设计成不可变类型的一个重要前是因为它是编程语言里面使用频率最高的一种类型。不可变类型带来的好处,体现在四个方面,分别是:缓存,安全,同步和性能。

(一)缓存

在JVM的运行时数据区域里面,有一个专门的字符串常量池用来存储字符串字面量,如下面一段代码:

String s1 = "Hello World";

String s2 = "Hello World";

assertThat(s1 == s2).isTrue();

s1和s2变量指针的内存地址其实是一样的,也就是说他们代表是同一个对象,这是jvm常量池做的优化,当第一个字面量声明的时候,它的值会被字符串常量池存储,当s2变量声明的时候,jvm发现常量池已经存在该对象,所以就不会再创建一次,而是直接将一样的内存指针赋值给s2变量,从避免了重复创建对象,节省了内存空间。

此外,由于字符串的不可变性,从而可以让其hashCode也被缓存,在Java里面哈希类数据结构如HashMap, HashTable, HashSet其key用的最多的基本都是String类型,如此一来key的hashCode的也可以在第一次调用之后被缓存,之后直接使用无须重新生成,从而间接的提升访问效率。

(二)安全

不可变特性也能够减少了应用程序在运行时间的安全问题,如下面的一段代码:

void criticalMethod(String userName) {

// check

if (!check(userName)) {

throw new SecurityException();

}

// query

query(userName);

}

在上面的一段代码,在调用这个方法之后,先检查用户名,如果合法才可以继续查询相关数据,如果String可变,那么攻击者就可以在通过check验证之后,再改变查询的用户名,那么就会存在安全风险,而不可变性能够避免和减少这一情况。另一方面,如果String是可变的,那么同时运行的其他线程如果修改这个值,就有可能导致混乱。

(三)同步

由于String类型的不可变性,使得String对象可以安全的在多个线程之间传递和访问,也就是说你在多线程中是不能改变字符串本身的值,而是在堆里面新创建一个字符串然后操作。当然如果没有final修饰,你是可以改变这个变量的引用地址,也就是说你可以把新生成的内存引用覆盖原来的变量引用,但这里仅仅是引用,并不是变量的值。这一点要注意。

(四)性能

性能方面,其实前面已经提到了,比如字符串的常量池节省内存,缓存Hash类以字符串做key数据结构的hashCode,从而提高访问性能等。由于字符串是编程语言里面最广泛使用的数据结构,所以针对字符串的不可变性带来的优势,可以放大到整个运行的应用程序,从而带来应用程序整体的性能提升。

总结:

本文主要介绍了Java语言里面String类型为什么设计成不可变类型,以及分析了不可变类型的带来的主要优势,需要注意的是虽然不可变类型能够带来不少的好处,但并不是说其没有弊端,不可变类型的每一次修改都需要在内存中新生成一个对象,从另一个方面说针对经常变化的对象是不适合使用不可变类型的,这也是为什么Java里面还提供了可修改值的StringBuilder和StringBuffer类,这在实际开发中常常是需要根据具体情况权衡的。

以上所述是小编给大家介绍的为什么Java里面String类是不可变的详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

本研究聚焦于地级以上城市,对资本、劳动力的空间错配程度进行了系统测度。借助时空核密度和综合协调指数,对城市资源空间错配的集聚模式及协调度展开细致分析,以期揭示城市资源空间错配在时空演变过程中的内在规律。不同资源型的城市空间错配程度在样本期内呈现出明显差异。城市资本和劳动力的空间错配,未能在不同地区、行业或企业之间实现最优配置,导致资源的边际产出不相等,从而偏离帕累托最优状态,造成效率损失和经济结构失衡。在地级市层面,资源错配问题尤为突出,主要表现为资本、劳动力和土地要素在城市间的配置不均衡。本数据包含原始数据、参考文献、代码、最终结果。原始数据资料:分城市财政收支083045349(仅供vip使用)分城市固定资产投资与消费075134218(仅供vip使用)分城市国内生产总值150425289(仅供vip使用)分城市金融统计文件083120235(到2023年)分城市人口、就业与工资150748455(仅供vip使用)分省份按城乡分全社会国定资产投资075038121(仅供vip使用)分省份固定资产投资价格指数075341115(仅到2019年)分省份国内生产总值150256154(仅供vip使用)分省份人口情况文件152110158(仅供vip使用)指数基本信息文件083840325(仅供vip使用)1998-2023固定资产投资价格指数.xlsxfinancial_data_analysis_report_wsl 20250903_205457.xlsxfinancial data_analysis_report_ wsl 20250903 205457_charts.pngn1.各地区进出口总额年度统计文件(按企业注册型分).csv樊纲1997-2019年市场化指数和各分项指数.xlsx樊纲1997-2023年市场化指数和各分项指数.xlsx分省份财政金融文件(1995-2023).csv分省份外商投资企业年底注册登记情况.csv复现说明.docx固定资产投资资金来源-年度(分省级).xlsx极速下载 各省资本存量数据2000-2023年(原始数据+测算+结果...相关数据及指标省 地级市 年份 资本错配指数 劳动力错配指数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值