首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java漫谈11

Java漫谈11

作者头像
用户1335799
发布2018-03-12 10:59:22
5790
发布2018-03-12 10:59:22
举报

这次我们接着聊String,这次我们聊聊String类为什么是final的。

之所以聊这个,是因为在知乎上看了一篇帖子,看完后让我对这个点有了认识,在这里跟你分享分享我的理解。

点击原文给你看这篇帖子。

总结来说,String之所以设计成final,是为了数据安全。

因为String不是8大基本的数据类型,所以String的值其实存的是一个内存地址,在这个地址就相当于存储值的那个仓库的编号。例如:

String a = "hello world";

这之中,a的实际值并不是hello world,而是类似于0x0045这样的内存地址值。因此,假设一种场景,假设String并不是final。此时,新定义一个变量b,并将变量a赋值给b。逻辑上是变量a将值赋给了变量b,可实际上是变量a将刚才提到的代表内存地址的“门牌号”赋值了了b。此时,如果我们要是修改b的值(变成“hello world-b”),其实,a的值也会一并修改。

而这样就与我之前的想要的逻辑结果不一致了,因为我只是仅仅想要b的值变成“hello world-b”,而a的值仍然保持“hello world”不变。

好,现在我们来看看在final修饰的场景下,String的结果又会怎样。注意,此时我们重新定义一下String的修饰场景,即String是有final修饰,但String并未启用常量池。同样是b复制了a的地址,b修改值,也就是b按照门牌号码找到仓库,去仓库里修改商品去了。所以b修改完之后,当a再顺着地址值(门牌号码)去提取商品信息的时候,发现商品也变了。

咦……这还是不对啊,实际当中的String遇到这种情况,结果是b变,a不变的呀。难道是常量池的作用,不对,常量池只是保证了读取速度的提高,而不会对值进行改变。如此一来,一个比较靠谱的解释就如文章中@胖胖所说:

所以 String 是不可变,关键是因为 SUN 公司的工程师,在后面所有 String 的方法里很小心的没有去动 Array 里的元素,没有暴露内部成员字段。

好了,逻辑分析完了,我想说说我自己弄清这些这个逻辑之后的感受。Java的String这个类是我在一开始学习的时候遇到的,起初一直把它误认为是一个基本的数据类型,以为它就是很简单的一个底层的实现。聊了这两期漫谈之后,才发现,在它平淡的外表下,原来隐藏着一个比较深的逻辑设计回路。而这个回路也正是工程师构造数据类型,封装数据功力的体现。

而这样的功力让我想到了一个词——静水流深。意思是通过表面平静的水并不知道水底有多深,来暗喻表面不声不响的人却藏着大智慧。我想这个词即适用于String这个类,也适用于构造String这个类的那些工程师们。

向String这个类,向构造这些类的工程师们致敬。愿你我有一天也能踏入这层境界。

清 单

  1. String的final主要的作用是保证了数据的安全。
  2. 表面上看它的数据安全来源于final的不可变性,实际上是来源于String类底层的封装。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-11-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 怀英的自我修炼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档