【 Java中String源码分析(JVM视角你不来看看?】

简介: 【 Java中String源码分析(JVM视角你不来看看?】

Java中String源码分析(JVM视角你不来看看?😊)

🎊专栏【Java】

🍔喜欢的诗句:关山难越,谁悲失路之人。 萍水相逢,尽是他乡之客。

🎆音乐分享【Counting Stars 】

欢迎并且感谢大家指出问题🥰

1.先来看看源码

众所周知, String 被声明为 final,因此它不可被继承。(Integer 等包装类也不能被继承)。当一个类被声明为final时,它就不能被继承,这是因为final类中的所有方法都被隐式地声明为final。这使得编译器能够优化代码,因为它们知道这些方法不会被子类覆盖。而String类正是因为它的一些关键方法(如equals()和hashCode())需要保持不可修改性,所以被设计为final类,以确保它们不会被继承。

先来看看 String 的源码。

在 Java 8 中,String 内部使用 char 数组存储数据。

Java9中则是这样的

上述我们看到value 数组被声明为 final,这意味着 value 数组初始化之后就不能再引用其它数组。并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。

2.String不可变有什么好处

2.1安全性

String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果String 是可变的,那么在网络连接过程中,String 被改变,改变 String 的那一方以为现在连接的是其它主机,而实际情况却不一定是。String 不可变性天生具备线程安全,可以在多个线程中安全地使用。

2.2缓存Hash值

因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash值也不可变,因此只需要进行一次计算。

2.3String Pool的使用

如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。

3.深入一下String

3.1+连接符

字符串对象可以使用“+”连接其他对象,其中字符串连接是通过 StringBuilder(或 StringBuffer)类及其append 方法实现的,对象转换为字符串是通过 toString 方法实现的。可以通过反编译验证一下:

由上可以看出,Java中使用"+"连接字符串对象时,会创建一个StringBuilder()对象,并调用append()方法将数据拼接,最后调用toString()方法返回拼接好的字符串。

那么他的效率怎么样呢?

使用“+”连接符时,JVM会隐式创建StringBuilder对象,这种方式在大部分情况下并不会造成效率的损失,不过在进行大量循环拼接字符串时则需要注意。比如:

这样由于大量StringBuilder创建在堆内存中,肯定会造成效率的损失,所以在这种情况下建议在循环体外创建一个StringBuilder对象调用append()方法手动拼接(如上面例子如果使用手动拼接运行时间将缩

小到1/200左右)。与此之外还有一种特殊情况,也就是当"+"两端均为编译期确定的字符串常量时,编译器会进行相应的优

化,直接将两个字符串常量拼接好,例如:

4.字符串常量

JVM为了提高性能和减少内存的开销,在实例化字符串的时候进行了一些优化:使用字符串常量池。每当

创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常

量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于

String字符串的不可变性,常量池中一定不存在两个相同的字符串。

看一个例子

由于常量池中不存在两个相同的对象,所以s1和s2都是指向JVM字符串常量池中的"AB"对象。new关键

字一定会产生一个对象,并且这个对象存储在堆中。所以 String s3 = new String(“AB”); 产生了两

个对象:保存在栈中的s3和保存堆中的String对象。

以上是从JVM视角去刨析更深层次的欢迎交流!!!


相关文章
|
2天前
|
Java 索引
String字符串常用函数以及示例 JAVA基础
String字符串常用函数以及示例 JAVA基础
|
4天前
|
Java 编译器 ice
【Java开发指南 | 第十五篇】Java Character 类、String 类
【Java开发指南 | 第十五篇】Java Character 类、String 类
23 1
|
2天前
|
存储 安全 Java
Java中的这些String特性可能需要了解下
Java中的String特性你知道哪些?虽然String很常见,通过源码可以看到String的值传递、字符串表和不可变性。本文基于JDK17说明。
9 1
|
2天前
|
存储 Java
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
|
2天前
|
Java 数据库连接 Spring
K8S+Docker理论与实践深度集成java面试jvm原理
K8S+Docker理论与实践深度集成java面试jvm原理
|
3天前
|
Java
Java String 避免空指针的方法
Java String 避免空指针的方法
5 0
|
4天前
|
安全 Java 编译器
Java中String、StringBuilder和StringBuffer的区别
Java中String、StringBuilder和StringBuffer的区别
10 1
|
4天前
|
Java 索引
深入浅出JVM(五)之Java中方法调用
深入浅出JVM(五)之Java中方法调用
|
4天前
|
Java 编译器 对象存储
java一分钟之Java入门:认识JDK与JVM
【5月更文挑战第7天】本文介绍了Java编程的基础——JDK和JVM。JDK是包含编译器、运行时环境、类库等的开发工具包,而JVM是Java平台的核心,负责执行字节码并实现跨平台运行。常见问题包括版本不匹配、环境变量配置错误、内存溢出和线程死锁。解决办法包括选择合适JDK版本、正确配置环境变量、调整JVM内存参数和避免线程死锁。通过代码示例展示了JVM内存管理和基本Java程序结构,帮助初学者更好地理解JDK和JVM在Java编程中的作用。
22 0
|
4天前
|
存储 监控 安全
JVM工作原理与实战(十六):运行时数据区-Java虚拟机栈
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了运行时数据区、Java虚拟机栈等内容。
12 0