String类有很多的构造函数
1、直接赋值一个字符串
2、new String(String original)
3、new String(char[] a)
4、new String(char[] a,int offset,int count)
对应的String的创建机制:
1、直接赋值的时候,现在
常量池
中寻找是否有对应的字符串,如果有,直接将引用变量指向常量池中字符串的地址;如果没有,则在常量池里面创建该字符串,再将其地址赋值给引用变量.
2、new String(String original)创建的时候,先在堆
中创建一个字符数组空间,然后再去常量池中寻找是否有对应的字符串,若有,则将常量池中该字符串赋值给堆中的字符串数组,然后将引用变量指向该数组;如果无,则现在常量池里边创建该字符串,然后将常量池中该字符串赋值给堆中的字符数组,然后将引用变量指向该数组.(常量池——> 堆中的字符串数组——> 变量
)
String 类型的相加
1、以下情况会在常量池中之杰生成hellworld的字符串,并将该字符串的地址赋值给引用变量
1、String str = "hello"+"world";
2、String str = "helloworld";
2、以下情况的字符串相加会先创建String Builder对象,然后调用String Builder的append()方法做字符串的拼接,并返回该String Builder对象给引用变量str,此时不会在常量池里面创建"helloworld".
只要相加时,有一个加量是对象,则会创建StringBuilder进行append
1 String str1 = "hello";
String str2 = "world";
String str1 + str2;
2 String str1 = "hello";
String str = str1 + "world";
3 String str = new String("hello") + new String("world");
4 String str = new String("hello") + "world";
String的intern函数
因为不是所有的字符串创建方式都会在常量池中生成对应的字符串,而intern函数用于根据所给的字符串在常量池中创建对应的字符串.
jdk7以后,调用intern方法时,如果该字符串已经存在于常量池中,则将常量池中的引用直接返回;如果不存在,则在常量池中生成一个
对原字符串的引用
.
String str1 = "helloworld";
String str2 = str1.intern();
str1 == str2 ??? true 两者都指向常量池中的helloworld
String str1 = new String("helloworld");
String str2 = str1.intern();
str1 == str2 ??? false new 一个对象时,也会在常量池中创建一个对应的字符串.前者指向堆中的字符串对象,后者指向常量池中的字符串
上面两种情况是字符串已经存在于常量池中,再看下面两个例子
String s = new String("hello");
String str1 = s + "world";
String str3 = "helloworld";
str3 == str1 ??? 答案是 false str1 指向的是堆中的String Builder对象,而str3指向的是常量池中的"helloworld",所以两者不是同一对象.
String s = new String("hello");
String str1 = s + "world";
String str2 = str1.intern();
String str3 = "helloworld";
str3 == str1 ??? true str1是通过创建Stringbuilder来实现拼接的,str1的指向没有变,所以变的是str3的指向.
因为调用了str1的intern方法,所以会在常量池中生成一个对原字符串的引用,而这个引用实质上就是指向堆中的str1(StringBuilder对象),
而此时,创建str3的话,根据字符串的创建机制,str3就指向了str1,最终两者相等.