String 的创建方式
String的创建方式有两种:
-
直接赋值
此方式在方法区中字符串常量池中创建对象
String str = "hello";
-
构造器
此方式在堆内存创建对象
String str = new String("hello");
我们来看一段代码:
String str1 = "AB";
String str2 = "AB";
String str3 = new String("AB");
String str4 = "A";
String str5 = "B";
String str6 = "A" + "B";
String str7 = str4 + str5;
System.out.println("str1 == str2 result: " + (str1 == str2)); //true
System.out.println("str1 == str3 result: " + (str1 == str3)); //false
System.out.println("str1 == str6 result: " + (str1 == str6)); //true
System.out.println("str1 == str7 result: " + (str1 == str7)); //false
/**
* intern() 方法返回字符串对象的规范化表示形式。
* 对于两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true
*/
System.out.println("str1 == str7.intern() result: " + (str1 == str7.intern())); //true
System.out.println("str3 == str3.intern() result: " + (str3 == str3.intern())); //false
1)str1 == str2
String str1 = "AB";
String str2 = "AB";
System.out.println(str1 == str2); // true
- 当执行第一句时,JVM会先去常量池中查找是否存在AB,当存在时直接返回常量池里的引用;当不存在时,会在字符创常量池中创建一个对象并返回引用。
- 当执行第二句时,同样的道理,由于第一句已经在常量池中创建了,所以直接返回上句创建的对象的引用。
2)str1 == str3
String str1 = "AB";
String str3 = new String("AB");
System.out.println(str1 == str3); // false
- 执行第一句,同上第一句。
- 执行第二句时,会在堆(heap)中创建一个对象,当字符创常量池中没有‘AB’时,会在常量池中也创建一个对象;当常量池中已经存在了,就不会创建新的了。
3)str1 == str6
String str1 = "AB";
String str6 = "A" + "B";
System.out.println(str1 == str6); // true
- 由于”A”和”B”都是常量,编译时,第二句会被自动编译为‘String str6 = “AB”;
4)str1 == str7
String str1 = "AB";
String str4 = "A";
String str5 = "B";
String str7 = str4 + str5;
System.out.println(str1 == str7); // false
- 其中前三句变量存储的是常量池中的引用地址。
- 第四句执行时,JVM会在堆(heap)中创建一个以str4为基础的一个StringBuilder对象,然后调用StringBuilder的append()方法完成与str5的合并,之后会调用toString()方法在堆(heap)中创建一个String对象,并把这个String对象的引用赋给str7。
网友评论