Java字符串在内存中的管理

本文总结一下关于比较字符串使用 “==” 的情况。

上来先做题:
Java字符串在内存中的管理_第1张图片
image.png

结果:
image.png


怎么回事???

运行结果是不是还和上篇文章一样奇怪,是不是又想着是 Java 编译器捣的乱?打开 .class 文件:

Java字符串在内存中的管理_第2张图片
image.png
发现编译器除了对源代码进行了简单的格式化,并没有任何额外的操作。

代码分析

那结果是怎么来的?通过上节的讲解,我们知道 .class 文件是被加载到 JVM(Java虚拟机) 中运行的。那么,是不是JVM在执行的时候做了什么额外的操作?

一句句分析代码,在 JVM 中,当代码执行到 String s1 = "100" 时,会先看 常量池 有没有刚好是 "100" 的 字符串常量对象,如果没有,则在常量池中创建该对象并将 s1 引用指向该对象。

Java字符串在内存中的管理_第3张图片
image.png

PS:图中只是画出了 main 方法栈和相关对象在内存中的大致模拟,实际上 JVM 的内存管理比较复杂,有待深入研究。

继续执行 String s2 = "100",JVM 仍然会到常量池寻找值为 100 的字符串常量,由于执行了上句代码,发现常量池已经有了该对象,则直接将 s2 引用指向该对象,不会在常量池或堆内存创建新的对象。
Java字符串在内存中的管理_第4张图片
image.png

因为 “==” 判断的是两个引用是否指向同一个对象,所以执行打印结果为 true。

这时候执行到了 String s3 = new String("100") ,由于代码中加了一个 new 关键字,这个关键字就是告诉 JVM,你直接在堆内存中给我开辟一块新的内存。如下图所示:

Java字符串在内存中的管理_第5张图片
image.png

继续执行 String s4 = new String("100")

Java字符串在内存中的管理_第6张图片
image.png

由于两个引用 s3 和 s4 指向的不是同一个对象,所以打印结果是 false 了。

结论:

由以上抛出的问题我们知道了 String 类型对象不同的声明方式在内存中展现的形式是不一样的。
当我们比较两个字符串对象的内容时,无论声明方式是怎样的,都一定要使用 equals 方法,不能使用 “==”。


原文作者:清浅池塘
原文链接:https://zhuanlan.zhihu.com/p/27570687

你可能感兴趣的:(Java字符串在内存中的管理)