松鼠乐园 松鼠乐园
  • 注册
  • 登录
  • 首页
  • 快捷入口
    • Vue
    • Tensorflow
    • Springboot
    • 语言类
      • CSS
      • ES5
      • ES6
      • Go
      • Java
      • Javascript
    • 工具类
      • Git
      • 工具推荐
    • 服务器&运维
      • Centos
      • Docker
      • Linux
      • Mac
      • MySQL
      • Nginx
      • Redis
      • Windows
    • 资源类
      • 论文
      • 书籍推荐
      • 后端资源
      • 前端资源
      • html网页模板
      • 代码
    • 性能优化
    • 测试
  • 重大新闻
  • 人工智能
  • 开源项目
  • Vue2.0从零开始
  • 广场
首页 › Java › Java源码之String

Java源码之String

迦娜王
3年前Java
483 0 0

String这个类可以说是我们使用得最为频繁的类之一了,前几次去面试,都被问到String的底层源码,回答得都不是很好,今天就来谈谈一下String的源码。

Java源码之String

一、String类

Java源码之String

String类被是被final修饰的,表明该类不可被继承,有关于关键词final的作用,请移步我的另外一篇文章【JAVA】关键词final的作用。值得一提的是,StringBuilder,StringBuffer类都是被final修饰的。


二、String类的属性

Java源码之String

(1)char value[]

String底层的存储结构是一个字符类型的数组,同样也是被final修饰,因此一旦这个字符数组被创建后,value变量不可再指向其他数组,但是可以改变value数组中某一个元素的值。

(2)int hash

hash用来保存某一个String实例自己的哈希值,可以说是哈希值的一个缓存,因此String特别适合放入HashMap中,作为key来使用。每次插入一个键值対时,不需要重新计算key的哈希值,直接取出key的缓存hash值即可,在一定程度上,加快了HashMap的效率。

(3)long serialVersionUID

用于保证版本一致性。由于String实现了Serializable接口,因此需要拥有一个序列化的ID。序列化时,将此ID与对象一并写入到文件中,反序列化时,检测该类中的ID与文件中的ID是否一致,一致的话,说明版本一致,序列化成功。

三、String类的构造函数

(1)无参构造函数,创建一个空字符串,即””,用得地方不多。

Java源码之String

(2)接收一个String实例的构造函数

Java源码之String

(3)接收一个字符数组,利用Arrays.copyOf()方法进行拷贝

Java源码之String

进入到Arrays.copyOf()方法中,发现调用的是System.arraycopy()方法,Arrays.copyOf()方法如下

Java源码之String

而System.arraycopy()方法是一个本地方法,由其他语言实现。

从以上源码,可以看得出,这个构造方法没有直接使用传入的字符数组的引用,而是使用该数组的一个拷贝,保证了String类的不可变性。我们无法通过在外部改变此数组中某些元素的值,来改变构造后的String的值。

同样在toCharArray()方法中,也是返回一个基于字符数组的拷贝,并没有直接直接返回value数组。

Java源码之String

(4)接收一个字符数组,从offset位置开始复制,一共选取count位

Java源码之String

其他的构造函数的原理大同小异,这里就不再说明了。


四、String类的其他方法

(1)equals()方法

Java源码之String

String类重写了equals()方法,判断两个String实例代表的字符串是否相同。

判断规则:

如果两个Stirng实例压根就是一个对象,即它们的内存地址相同,则直接返回true。

之后,对anObject进行类型判断,类型为String后,继续判断,否则直接返回false。

再对两者的长度进行判断,如果相等,继续判断,否则返回false。

两者长度相等后,再从前往后依次比较两者字符数组中的元素是否相等,全相等的后,返回true。

equals()方法一上来没有直接比较两个字符串的字符数组元素,在比较超长的字符串时,节省了大量的时间。

(2)compareTo()方法

Java源码之String

比较两个字符串,可以用来排序。String类中还有一个内部类CaseInsensitiveComparator,其中也有一个compare()方法,与compareTo()方不同的是,compare()进行比较时,会忽略两个字符串的大小写。


(3)hashCode()方法

Java源码之String

String类同样也重写了hashCode()方法,用于计算String实例的哈希值。

哈希值相同的两个字符串不一定相同,相同的字符串的哈希值一定相同。

(4)intern()方法

Java源码之String

可以看得出,它是一个本地方法。

当调用此方法时,会首先在方法区中的常量池中使用equals()寻找是否存在此字符串,如果存在,直接返回此字符串的引用。如果不存在时,会首先将此字符串添加到常量池中,再返回该字符串的引用。

下面通过一个例子来说明

Java源码之String

五、总结

String类中还有很多有趣的操作,比如字符串的截取、匹配、替换、大小写转换、分割等操作,这里都没有涉及。这些操作确实都是经常用到的,相信大家也能够理解他们的用法,这里就不再赘述了。

以上就是我的对此问题的整理和思考。

0
万万没想到,JVM内存结构的面试题可以问的这么难?
上一篇
Java8新特性:默认方法详解
下一篇
评论 (0)

请登录以参与评论。

现在登录
聚合文章
Servicios profesionales Organizaciones
1年前
在Gitee收获近 5k Star,更新后的Vue版RuoYi有哪些新变化?
1年前
vue3.x reactive、effect、computed、watch依赖关系及实现原理
1年前
Vue 3 新特性:在 Composition API 中使用 CSS Modules
1年前
标签
AI AI项目 css docker Drone Elaticsearch es5 es6 Geometry Go gru java Javascript jenkins lstm mysql mysql优化 mysql地理位置索引 mysql索引 mysql规范 mysql设计 mysql配置文件 mysql面试题 mysql高可用 nginx Redis redis性能 rnn SpringBoot Tensorflow tensorflow2.0 UI设计 vue vue3.0 vue原理 whistle ZooKeeper 开源项目 抓包工具 日志输出 机器学习 深度学习 神经网络 论文 面试题
相关文章
Java基础知识」超级详细的Java基础知识,你还记得多少
学习java最基本的27个知识点你会吗?
要精通Java,先研究它的执行原理
java干货大集合
松鼠乐园

资源整合,创造价值

小伙伴
墨魇博客 无同创意
目录
重大新闻 Centos CSS Docker ES5 ES6 Go Java Javascript Linux Mac MySQL Nginx Redis Springboot Tensorflow Vue Vue2.x从零开始 Windows 书籍推荐 人工智能 前端资源 后端资源 壁纸 开源项目 测试 论文
Copyright © 2018-2022 松鼠乐园. Designed by nicetheme. 浙ICP备15039601号-4
  • 重大新闻
  • Centos
  • CSS
  • Docker
  • ES5
  • ES6
  • Go
  • Java
  • Javascript
  • Linux
  • Mac
  • MySQL
  • Nginx
  • Redis
  • Springboot
  • Tensorflow
  • Vue
  • Vue2.x从零开始
  • Windows
  • 书籍推荐
  • 人工智能
  • 前端资源
  • 后端资源
  • 壁纸
  • 开源项目
  • 测试
  • 论文
热门搜索
  • jetson nano
  • vue
  • java
  • mysql
  • 人工智能
  • 人脸识别
迦娜王
坚持才有希望
1224 文章
35 评论
242 喜欢
  • 0
  • 0
  • Top