JAVA字符串拼接和intern的方法小细节(JDK1.8)
JAVA字符串拼接
我们都知道创建字符串的方法有两种:
- String s4=new String(“11”);
- String s5=“11”;
我们也都知道二者的区别
一个是生成了一个字符串对象,存在于堆空间中,还生成了一个字符串常量存在于常量池中;另外是生成了一个字符串常量存在于常量池中。
String s4=new String(“11”);
String s5=“11”;
我们还知道
如果是一个字符串加一个new的string对象会转换成new的string对象,那么两个new的string对象会生成多少个对象呢
String s3=new String("he")+new String("llo");
//大部分人说是5个,其实是六个
/**
* 如下的s1 + s2的执行细节:
* stringBuilder s = new stringBuilder();
* s.append("a")
* s.append("b")
* s.tostring() -->类似于new string( "ab")
* */
六个对象:
- new的"he"对象
- new的"llo"对象
- 常量池的he
- 常量池的llo
- 拼接的hello
- stringbuilder的tostring方法new的对象
这里我们要记住,字符串常量池中并没有生成hello这个常量,而且拼接字符串的操作是用springbuile的append方法生成的。
inter方法的细节
调用intern()方法,首先判断常量池中是否存在该字符串,如果存在则返回该字符串常量池的地址;如果不存在,则主动将常量池中还没有的字符串对象放入池中,并返回此对象地址。
补充:Jdk1.7起,将这个字符串对象尝试放入串池。如果串池中有,则并不会放入。返回已有的串池中的对象的地址如果没有,则会把对象的引用地址复制一份,放入串池,并返回串池中的引用地址
代码测试:
@Test
public void test2() {
String s1 = "JavaEE";
String s2 = "hadoop";
String s3 = "JavaEEhadoop";
String s4 = "JavaEEhadoop";
String s5 = s1 + "hadoop";
String s6 = "JavaEE" + s2;
String s7 = s1 + s2;
System.out.println(s3 == s4); //true
System.out.println(s3 == s5); //falase
System.out.println(s3 == s6); //falase
System.out.println(s3 == s7); //falase
System.out.println(s5 == s6); //falase
System.out.println(s5 == s6); //falase
System.out.println(s6 == s7); //falase
String s8 = s6.intern();
System.out.println(s3 == s8); //true
System.out.println(s4 == s8); //true
System.out.println(s5 == s8); //false
System.out.println(s6 == s8); //false
}
@Test
public void test4(){
String str = new String("pingtouge");
String str1 = new String("pingtouge");
System.out.println("未使用intern()方法:"+(str==str1));
System.out.println("未使用intern()方法,str:"+str);
System.out.println("未使用intern()方法,str1:"+str1);
String str2= new String("pingtouge").intern();
String str3 = new String("pingtouge").intern();
System.out.println("使用intern()方法:"+(str2==str3));
System.out.println("使用intern()方法,str2:"+str2);
System.out.println("使用intern()方法,str3:"+str3);
}
public static void main(String[] args) {
String s3=new String("1")+new String("1");
String intern = s3.intern();
System.out.println(s3=="ab"); //true
System.out.println(intern=="ab"); //true
}
public static void main(String[] args) {
String s3=new String("1")+new String("1");
System.out.println(s3=="11"); //false
String intern = s3.intern();
System.out.println(intern=="11"); //true
}
public static void main(String[] args) {
String s3=new String("1")+new String("1");
String s4="11";
String intern = s3.intern();
String s5="11";
System.out.println(s3==s4); //false
System.out.println(s3==s5); //false
System.out.println(s4==s5); //true
System.out.println(intern==s5); //true
}
public static void main(String[] args) {
String s3=new String("1")+new String("1");
String intern = s3.intern();
String s4="11";
String s5="11";
System.out.println(s3==s4); //true
System.out.println(s3==s5); //true
System.out.println(s4==s5); //true
System.out.println(intern==s5); //true
}
所以从上面可以看出,如果常量池中不存在这个对象,inter方法会在常量池中创建一个引用指向堆空间的这个对象,如果常量池中存在,inter方法无实际效果。