Java漫谈11

这次我们接着聊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类底层的封装。

原文发布于微信公众号 - 怀英的自我修炼(hydzwxl)

原文发表时间:2017-11-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一名叫大蕉的程序员

JVM知识点总览:高级Java工程师面试必备

程序员,就是“一人,一键,二机”行走其间的孤独剑客。我们游走代码江湖,弹指间,便可掀起一场风雨变革。而在江湖中狂荡,必然要练就绝世武功,则需要内外兼备:精妙的招...

492
来自专栏Python

MongoDB

一 简介 MongoDB是一款强大、灵活、且易于扩展的通用型数据库 1、易用性 MongoDB是一个面向文档(document-oriented)的数据库,而不...

2706
来自专栏搜云库

Spring Boot 中使用 MongoDB 增删改查

本文快速入门,MongoDB 结合SpringBoot starter-data-mongodb 进行增删改查

3447
来自专栏铭毅天下

干货 | 吃透Elasticsearch 堆内存

1、什么是堆内存? Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。 在 Java 中,堆被划分成两个不同的区域: 新生代...

2884
来自专栏数据小魔方

R语言数据处理——数据合并与追加

数据结构的塑造是数据可视化前重要的一环,虽说本公众号重心在于数据可视化,可是涉及到一些至关重要的数据整合技巧,还是有必要跟大家分享一下的。 在可视化前的数据处理...

2659
来自专栏java一日一条

优秀的Java程序测试是什么样的?

作为测试驱动设计和开发的忠实粉丝,我相信创造良好的测试是我们作为Java开发人员可以做的最重要的事情之一。我们写测试出于许多原因:

501
来自专栏Crossin的编程教室

【每周一坑】验证哥德巴赫猜想

哥德巴赫在 1742 年给欧拉的信中提出了以下猜想:任一大于 2 的整数都可写成三个质数之和。(因现今数学界已经不使用“1 也是质数”这个约定,原初猜想的现代陈...

3309
来自专栏北京马哥教育

编码的秘密(python版)

? ? 编码(python版) 最近在学习python的过程中,被不同的编码搞得有点晕,于是看了前人的留下的文档,加上自己的理解,准备写下来,分享给正在...

3027
来自专栏Java架构

今咱们来聊聊JVM 堆外内存泄露的BUG是如何查找的

JVM的堆外内存泄露的定位一直是个比较棘手的问题。此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤了Bug的源头。笔...

49617
来自专栏恰同学骚年

操作系统核心原理-3.进程原理(上):进程概要

进程管理、内存管理和文件管理是操作系统的三大核心功能,那么什么是进程呢?顾名思义,进程就是进展中的程序,或者说进程是执行中的程序。当一个程序被加载到内存之后就变...

752

扫描关注云+社区