intern() 函数
intern() 函数是一个native方法,也就是用 C++/C 实现的方法,编译成dll供java调用。
str.intern();
它的作用是,在字符串常量池中查找是否有与 字面量对象str (不是new出来的那个对象) 的引用相同的引用,如果有,则返回这个引用;如果没有,则在字符串常量池中增加该字面量对象的引用,并返回这个引用。
用一个例子来加深理解:
String s1 =new String("hello");
String s2 = s1;
s1 = s1.intern();
System.out.println(s2==s1);
-
第1句,在堆中创建了两个不同的对象。常量池保存了堆中第一个字面量对象的引用,s1接收了堆中第二个new出来的对象的引用。
-
第2句,引用传递,此时s1和s2指向同一个对象(new出来的那个对象,第二个生成的)。
-
第3句,去字符串常量池中 查找是否有与字面量对象("hello"字符串对象,第一个生成的)引用相同的引用,现在是有的,返回这个引用给s1,s1被覆盖。那么现在这个引用和最开始s1引用所指向的是在堆中两个不同的对象
所以,当前s1和s2所指向的是在堆中两个不同的对象,所以输出为false。
现在如果把第三句改为 s1.intern(); ,即去掉等号之前的部分,那么输出变为true,说明s1的值没有被覆盖,因为返回的值没有任何东西去接收,所以此时s1和s2仍然指向同一个对象。
再来一个例子加深理解:
String str1 = new String("def");
String str2 = str1.intern();
String str3 = "def";
System.out.println(str1 == str2);//false
System.out.println(str2 == str3);//true
-
第1句在堆中创建了两个不同的对象。常量池保存了堆中第一个字面量对象的引用,str1接收了堆中第二个new出来的对象的引用。
-
第2句会把堆中字面量对象“def”的引用(在字符串池中)返回给str2 。
-
第3句的目的是在堆中创建一个字面量对象“def”,但此时已经存在,所以不会重新创建,str3直接接收字面量对象“def”在常量池中的引用。
因此,str1 != str2,因为他们指向的不是一个对象,s1指向第一行代码new出来的那个,s2指向第一行代码生成的字面量对象 ;而s2==s3,因为他们都指向第一行代码生成的字面量对象。