当前位置:网站首页>深入源码剖析String类为什么不可变?(还不明白就来打我)
深入源码剖析String类为什么不可变?(还不明白就来打我)
2022-07-26 20:58:00 【努力努力再努力Gzc.】
一、什么是不可变?
String不可变其实很简单,如下图所示,对一个已有字符串s=“abcd”,把它第二次赋值成"abcdel",这个操作并不会在原内存地址(即“abcd”的内存地址)上修改数据,而是重新指向一个新的内存地址(即“abcdel”)。所以并不是我们一般会认为的鸠占鹊巢——“abcdel”替换了“abcd”,占据了“abcd”的内存位置,导致“abcd”无家可归,从这个世界上消失。
二、String不可变的本质
查看以下jdk中String类的源码:
(这里只列出了前三行,大家有兴趣可以自行去查看完整源码)
我们发现
(一)String类是一个final类。
String类由final修饰,我们都知道当final修饰一个类时,该类不可以被其他类继承,自然String类就没有子类,也更没有方法被子类重写的说法了,所以这就保证了外界无法通过继承String类,来实现对String不可变性的破坏。
(二)String底层是通过一个char[]来存储数据的,且该char[]由private final修饰。
该value数组被final修饰,我们知道被final修饰的引用类型的变量就不能再指向其他对象了,也就是说value数组只能指向堆中属于自己的那一个数组,不可以再指向其他数组了。但是这不妨碍我们可以改变它指向的这个数组里面的内容啊,比如咱们随便举个例子:

那外部的破坏者可能就想了,既然你不让我改变value数组的指向,那我修改它里面的内容不就行了,嘿嘿
然后他就想着通过访问这个value数组来修改里面的值,但是操作的时候他发现,他.不出来这个value数组,这他就纳闷了,怎么会访问不到呢?
其实这个时候就是private起作用了,有了private外界自然就访问不到我这个value数组,自然也就修改不了我里面的数据了。
好了,现在外部想要破坏我们String类不可变性的路都被堵死了,那也得保证内部不能出“奸细”啊,不能闹笑话不是!
(三)String类内部没有向外界提供或者暴露任何可以更改value数组的方法。
纵观源码,我们发现String类内部也没有向外界提供或者暴露任何可以更改value数组内容的方法,所以内部的安全也就保证了,这样一来外部内部都无懈可击。这就达到了我们String类不可变性的最终目的了!
三、总结
保证String类不可变靠的就是以下三点:
(一)String 类被 final 修饰导致其不能被继承,进而避免了子类破坏 String 不可变性。
(二)保存字符串的value数组被 final 修饰且为私有的。
(三)String 类里没有提供或暴露修改这个value数组的方法。
边栏推荐
- Ren Zhengfei talked about the suppression of the United States again: to live is to win, and to defeat the United States
- 加载 iframe 时显示加载指示器
- 拼多多获得搜索词推荐 API
- Filtering and distortion
- 传三星从比利时获得EUV光刻胶
- The United States once again challenged: Forbidding contractors to purchase the equipment and technology of these five Chinese companies
- 我的sql没问题为什么还是这么慢|MySQL加锁规则
- 会用redis吗?那还不快来了解下redis protocol
- js点击图片打印图像
- 六、微信小程序发布流程
猜你喜欢

补充—非线性规划

FreeRTOS personal notes - Software Timer

js中join方法

Logical vulnerability - arbitrary account registration

7、 Wechat applet running error: error: illegal appid, invalid appid

5、 Applet error: message:error: system error, error code: 80058, desc of scope userLocation is empty

京东一面:Redis 如何实现库存扣减操作?如何防止商品被超卖?

Devops has been practiced for many years. What is the most painful thing?

JDBC总结

六、微信小程序发布流程
随机推荐
FreeRTOS personal notes - Software Timer
Pytorch squeeze() unsqueeze() 用法
JS click the picture to print the image
Cfdiv1+2-pathwalks- (tree array + linear DP)
在上传之前预览图像
5、 Applet error: message:error: system error, error code: 80058, desc of scope userLocation is empty
A new technical director asked me to do an IP territorial function~
获取文本选择的方向
力扣每日一题-第43天-168. Excel表列名称
Object.getOwnPropertyNames() VS Object.keys()
Pytorch torch.add() torch.add_() 用法
伟创力回应“扣押华为物料”事件:深感遗憾,期待继续合作!
FreeRTOS personal notes - Events
Happens-Before原则深入解读
ECCV 2022 | complete four tracking tasks at the same time! Unicorn: towards the unification of target tracking
MySQL -count: the difference between count (1), count (*), and count (column name)
Flag decodes token, mounts token, decorator, and seven cattle cloud upload
虾皮shopee根据关键词取商品列表 API
Drag and drop table rows
月薪5万的朋友告诉我,你只是在打杂