一 Intern方法作用
1.1 Intern方法
1.在jdk1.6中:
intern()方法:在jdk1.6中,根据字符串对象,检查常量池中是否存在相同字符串对象
如果字符串常量池里面已经包含了等于字符串X的字符串,那么就返回常量池中这个字符串的引用;
如果常量池中不存在,那么就会把当前字符串添加到常量池并返回这个字符串的引用
2.在jdk1.7中:
intern()方法:在jdk1.7中,根据字符串对象,检查常量池中是否存在相同字符串对象
如果字符串常量池里面已经包含了等于字符串X的字符串,那么就返回常量池中这个字符串的引用;
如果常量池中不存在,那么就会创建指向堆中字符串对象的引用。
注意jdk1.7之前和之后,对于常量池不存在指定字符串,不同的处理逻辑。
1.2 案例解析
本案例使用jdk17进行操作。
1.new String(“a”)必定会在堆中会生成一个对象,不过可能是匿名的,同时也会在常量池中生成一个常量“a”(如果a还在常量池中的话)。https://blog.51cto.com/u_16099168/10402353
2.“a”+“b”并不会在常量池中生成常量池“ab”,只会生成“a”和“b”,因为字符串连接的结果是运行时才能确定的,编译无法确定,最终会返回一个存在堆中的“ab”字符串连接。
1.2.1.代码
String str1 = new String("hello");
String str2 = str1.intern();
String str3="hello";
System.out.println("str1==str2:"+(str1==str2));
System.out.println("str1==str3:"+(str1==str3));
System.out.println("str2==str3:"+(str2==str3));
System.out.println("=============");
String str11 = String.valueOf(22);
String str12 = str11.intern();
String str13 = "22";
System.out.println("str11==str12:"+(str11==str12));
System.out.println("str11==str13:"+(str11==str13));
System.out.println("str12==str13:"+(str12==str13));
str1==str2:false
str1==str3:false
str2==str3:true
=============
str11==str12:true
str11==str13:true
str12==str13:true
1.2.2.分析
案例1:
1.new String(“hello”)必定会在堆中会生成一个对象,不过可能是匿名的,同时也会在常量池中生成一个常量“11”(如果11还在常量池中的话)。https://blog.51cto.com/u_16099168/10402353
2.当调用string的intern方法时,会检查常量池中是否已存在“hello”字符串,如果存在则那么就返回常量池中这个字符串的引用;这里是存在,则直接返回引用地址给s2;
3.s3在赋值时给了一个字面量,直接使用字符串常量池的内容,直接返回引用地址给s3;
案例2:
在jdk1.7以前,运行时常量池存在于方法区,而在jdk1.7开始,运行时常量池被移动到了堆区,这使得,如果调用intern()时,发现常量池中并没有该字符串常量,那么不需要再创建一个常量,而是直接创建指向堆中字符串对象的应用,相当于重用了字符串对象。