关于常量池的分析
第一种情况
public class Dome {
public static void main(String[] args) {
String s1 = "ab";
String s2 = "ab";
System.out.println(s1 == s2);
}
}
//ture
对应的内存分析图
第二种情况
public class Dome {
public static void main(String[] args) {
String s1 = "a" + "b";
String s2 = "ab";
System.out.println(s1 == s2);
}
}
//ture
内存图分析:
编译器会进行优化,在编译阶段会把“a”,"b",优化成
字符串“ab”,然后再类加载阶段,把ab字符串纳入到
字符串常量池中。
第三种情况
public class Dome {
public static void main(String[] args) {
String s1 = new String("a") + new String("b");
//会在堆中创建一块新的空间,并将该空间的地址执行栈中引用这个字符串的变量
s1.intern();
String s2 = "ab";
System.out.println(s1 == s2);
}
}//ture
内存图分析:
当调用s1.intern()方法的时候,会做以下判断
查看当前字符串("ab")在常量池中是否存在
①:存在若栈中有引用,则返回该字符串(“ab”)在常量池中的地址给栈中引用这个字符串的变量。
若栈中没有引用,则什么也不做。②:不存在
直接将堆中(不是字符串常量池中)该字符串的地址复制到字符串常量池中,这
样字符串常量池就有了该字符串的地址引用,也可以说此时字符串常量池中的字
符串只是一个对 堆中字符串对象的引用,它们两个的地址相同,然后再把这个地
址返回给栈中要引用这个字符串的变量。
第四种情况
public class Dome {
public static void main(String[] args) {
String s1 = new String("ab");
s1.intern();
String s2 = "ab";
System.out.println(s1 == s2);
}
}
//false
内存图分析
当执行第一行代码的时候,首先去常量池中找字符串“ab”。
如果找到了,则不在字符串常量池中创建一个新对象,直接将堆引用指向字符
串“ab”在常量池中的地址。如果找不到,此时在堆中和常量池中都会创建该字符串的对象,但是他们地址不
同,一个是堆中对象的地址,一个是字符串常量池中的地址。并让堆中的引用指
向字符串常量池中的地址。调用intern()方法之前,此时常量池中已经有“ab”,并且栈中
没有任何引用。因此,什么也不做。当执行第三行代码的时候,因为此时常量池中已经有字符串“ab”,所以此步只是把new
String("ab")在常量池中创建“ab”对象的地址赋值栈中引用s2。
第五种情况
public class Dome {
public static void main(String[] args) {
String s1 = new String("ab");
String s3 = s1.intern();
String s2 = "ab";
System.out.println(s3 == s2);
}
}
//ture
内存图分析
当执行第一行代码的时候,首先去常量池中找字符串“ab”。
如果找到了,则不在字符串常量池中创建一个新对象,直接将堆引用指向字符
串“ab”在常量池中的地址。
如果找不到,此时在堆中和常量池中都会创建该字符串的对象,但是他们地址不
同,一个是堆中对象的地址,一个是字符串常量池中的地址。并让堆中的引用指
向字符串常量池中的地址。
调用intern()方法之前,此时常量池中已经有“ab”,但是栈中
有引用s2,因此,将常量池中的地址返回给s2
当执行第三行代码的时候,因为此时常量池中已经有字符串“ab”,所以此步只是把new
String("ab")在常量池中创建“ab”对象的地址赋值栈中引用s3。
第六种情况
public class Dome {
public static void main(String[] args) {
String s1 = new String("a") + "b";
String s3 = s1.intern();
String s2 = "ab";
System.out.println(s3 == s1);
}
}//ture
内存图分析
第七种情况
public class Dome {
public static void main(String[] args) {
String s1 = new String("a") + "b";
String s2 = "ab";
String s3 = s1.intern();
System.out.println(s3 == s1);
}
}//false
内存图分析
标签:分析,ab,String,s1,池中,关于,字符串,常量 From: https://www.cnblogs.com/xuzhidong/p/16871063.html