本文总结一下关于比较字符串使用 “==” 的情况。
上来先做题: image.png 结果: image.png怎么回事???
运行结果是不是还和上篇文章一样奇怪,是不是又想着是 Java 编译器捣的乱?打开 .class 文件:
image.png 发现编译器除了对源代码进行了简单的格式化,并没有任何额外的操作。代码分析
那结果是怎么来的?通过上节的讲解,我们知道 .class 文件是被加载到 JVM(Java虚拟机) 中运行的。那么,是不是JVM在执行的时候做了什么额外的操作?
一句句分析代码,在 JVM 中,当代码执行到 String s1 = "100" 时,会先看 常量池 有没有刚好是 "100" 的 字符串常量对象,如果没有,则在常量池中创建该对象并将 s1 引用指向该对象。
image.png继续执行 String s2 = "100",JVM 仍然会到常量池寻找值为 100 的字符串常量,由于执行了上句代码,发现常量池已经有了该对象,则直接将 s2 引用指向该对象,不会在常量池或堆内存创建新的对象。 image.pngPS:图中只是画出了 main 方法栈和相关对象在内存中的大致模拟,实际上 JVM 的内存管理比较复杂,有待深入研究。
因为 “==” 判断的是两个引用是否指向同一个对象,所以执行打印结果为 true。
这时候执行到了 String s3 = new String("100") ,由于代码中加了一个 new 关键字,这个关键字就是告诉 JVM,你直接在堆内存中给我开辟一块新的内存。如下图所示:
image.png继续执行 String s4 = new String("100")
image.png由于两个引用 s3 和 s4 指向的不是同一个对象,所以打印结果是 false 了。
结论:
由以上抛出的问题我们知道了 String 类型对象不同的声明方式在内存中展现的形式是不一样的。
当我们比较两个字符串对象的内容时,无论声明方式是怎样的,都一定要使用 equals 方法,不能使用 “==”。
网友评论