分析1
我们先看以下代码:
java
String str1 = "abc"; // 在常量池中
String str2 = new String("abc"); // 在堆上
System.out.println(str1 == str2)
以上结果的输出是什么?
输出:false
前置知识:
-
在JVM中,对象的创建默认在堆中。
-
字符串常量池(String Pool):Java中有一个特殊的区域称为字符串常量池。这个区域用来存储字符串常量,可以帮助节省内存,因为它确保所有相同的字符串常量都共享同一份内存。如果常量池中已经存在相同的字符串,就不会再创建新的相同字符串。
分析如下:
Java为了提高访问效率,当你 对一个字符串直接赋值时, 也就是执行第一句语句的时候,它会在方法区的字符串常量池中生成一个对应的字符串, 把该地址传递给 str1。当你 new 一个新的字符串时,它首先会检查 方法区中字符串常量池 中是否有对应的字符串,如果没有,则会持续生成一份。接着会在 JVM堆 中生成一个新的对象,把该对象在堆的引用传递给 str2。所以他们两个是不相等的。
分析2
java
String str1 = "abc"; // 在常量池中
String str2 = "abc"; // 在堆上
System.out.println(str1 == str2)
以上结果的输出是什么?
输出 true
通过以上的分析你应该知道,第二个str2 会直接去字符串常量池中查找有无对应的字符串,如果有,直接返回该地址,所以str1和str2指向的是同一个地址空间,答案为true。
分析3
java
String str1 = "abc"; // 在常量池中
String str2 = "abc"; // 在堆上
System.out.println(str1.equals(str2)
以上结果的输出是什么?
输出 true
String 类重写了 equals方法,它不是比较地址,是直接比较字符串的内容是否相等。
参考:参考1