Java字符串在内存中的管理

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

上来先做题:
image.png

结果:
image.png


怎么回事???

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

image.png
发现编译器除了对源代码进行了简单的格式化,并没有任何额外的操作。

代码分析

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

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

image.png

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

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

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

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

image.png

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

image.png

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

结论:

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


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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 161,656评论 24 692
  • 第2章 小圣贤庄 最后林悦槿跟着天明等人去了小圣贤庄,被安排在一个普通弟子的房间,不过是单人的,她看了一...
    萝卜一米五阅读 316评论 0 1
  • 杰克·特劳特(Jack Trout) 全球最顶尖的营销战略家,“定位”之父。 1969年提出商业中的“定位”观念,...
    茶了喵阅读 166评论 0 0
  • 纸鸢不解情,却作柔情绕。飞雪无心意,可慰怨人哀。愿天知我意,代慰故人缄。依依作耳语,诺诺携手还。依稀梦童年,并髻笑...
    骄阳慕雪阅读 195评论 4 2