java字符串的扣留机制是对字符串常量池的操作。intern()方法是将本字符串拷贝到字符串常量池中,除非字符串常量池中已经有内容与本字符串相同的字符串,然后返回字符串常量池中与之相同的字符串对象的引用
为了理解扣留机制,我做了一下测试代码
(1)参照程序
String s1="m";
String s2="n";
String s3=s1+s2;
String s4=s1+s2;
System.out.println(s3==s4);
结果是false;这个证明String s3=s1+s2;String s4=s1+s2;两次运行的s1+s2是运行了两次加法,生成的是两个字符串
(2)测试程序1
String s1="m";
String s2="n";
String s3=s1+s2;
String s4=s1+s2;
s3.intern();
s4.intern();
System.out.println(s3==s4);
s3=s3.intern();
s4=s4.intern();
System.out.println(s3==s4);
运行结果是false
true
证明ntern();方法本身不能改变字符串的信息,而是要通过返回新的引用(来自字符串常量池的)
(3)测试程序2
String s1="m";
String s2="n";
String s3=s1+s2;
String s4=s1+s2;
s4=s4.intern();
String s5=s1+s2;
s5=s5.intern();
System.out.println(s4==s3);
System.out.println(s4==s5);
结果是false
true
这是因为字符串扣留方法intern();是在字符串常量池中寻找与之是否有相同的字符串,而s3是不再字符串常量池中的.而后s4.intern();将自身加入到字符串常量池中,所以在执行s5=s5.intern();时,由于已经有与之相同的字符串常量"mn",不再加入新的字符串。即字符串常量池相同内容字符串只有一个
(4)程序测试3
String s1="m";
String s2="n";
String s3=s1+s2;
s3=s3.intern();
String s4="mn";
System.out.println(s4==s3);
结果是true.
似乎s4="mn"是在s3之后创建的。但是这里的关键是"mn"是在编译过程中已经创建并且放到字符串常量池中了,所以它是先创建的
(5)程序测试4
String s1="m";
String s2="n";
String s3=s1+s2;
System.out.println(s3.intern()==s3);
结果是false
说明是拷贝一个新的字符串对象而不是直接注册原来的字符串引用