JVM基础之数组与字符串

256 阅读3分钟

简介

本篇文章首先简单的介绍一下数组,因为数组与字符串有着不可分割的关系。随后会对字符串做详尽的讲解,包括字符串的创建原理、字符串常量池、字符串内存结构、字符串拼接,intern等内容

数组

数组最大长度

想要知道数组最大可以为多长,就要先知道数组的长度是怎么记录的?

数组长度是存储在对象头里,且用无符号4字节表示,所以最大是 2的32次方减1

image.png

数组与字符串的关系

image.png

字符串

字符串常量池

字符串常量池,在jvm中对应的是StringTable,它继承了hashtable,也就是说底层数据结构是hashtable

image.png

既然是hashtable那就肯定要生成,key与value

key的生成

key的生成规则是,用内容与长度进行hash运算,再用得到的hash值转为key

image.png

value的生成

value的生成规则是将java的实例(对应c++的instance OopDesc)封装成HashtableEntry

image.png

内存结构

下面用常见几段代码分析各个情况的内存结构

第一种

看这段代码的内存结构

String str1 = "123";

image.png

证明

有了以上的理论我们借助idea看点实际的东西

工具使用

image.png

单步运行后内存变化,可以看到char[]多了一个

image.png

第二种

public static void main(String[] args) {
   String str1 = "123";
   String str2 = "123";

   System.out.println(str1 == str2);
}

image.png 证明

image.png

image.png

image.png

从内存变化中可以看到 str2并没有创建新的cha[]与string,换言之,str1与str2指向的是同一个对象。

image.png

第三种

public static void main(String[] args) {
   String str1 = new String("123");

    String str2 = new String("123");

   System.out.println(str1 == str2);
}

image.png 证明

image.png

image.png

image.png

== 与equals

了解了内存结构后这个问题就简单了, == 是比较是否为同一个对象,equals是比较值

字符串拼接

第一种

public static void main(String[] args) {
    String str1 = "1" +"2";
}

反编译class可以看到这种情况被编译优化了

image.png

第二种

public static void main(String[] args) {
    String str1 = "1";
    String str2 = "2";
    
    String s3 = str1 + str2;
}

通过字节码可以看到是用StringBuilder进行append

image.png

第三种

public static void main(String[] args) {
    final String str1 = "1";
    final String str2 = "2";

    String s3 = str1 + str2;
}

这种情况会被当成常量,也会被编译器优化

image.png

综合练习

image.png

String三个参数的构造函数

image.png

image.png

image.png

通过内存变化可见(右下角),使用三个参数的构造函数创建字符串没有创建常量池的引用的,所以str2 = “12”时还会生成一个String对象与一个char[]

image.png

intern

public static void main(String[] args) {

   String str = new String(new char[]{'1','2'},0,2);
   str.intern();
   String str2 = "12";
    System.out.println(str == str2);
}

将上述例子稍作改动,加一个str.intern,最终结果就变成了true,因为intern的执行过程是,先看字符串常量池中有没有该字符串的引用,如果有则直接返回,否则创建引用。

image.png

以上就是本篇文章要分享的全部内容,拜拜~。