String相关问题
String类的不可变设计
String类设计为不可变,final修饰String类,表示String类不能被继承;final修饰value数组字段,被赋值后不可改变,同时value字段是私有的,没有对外暴露。
String不可变的优点:
- String类型使用最多,参数传递时更加安全。
- 在多线程下绝对安全。
- 字符串在常量池中共享,节约内存,提高效率。
substring/replace/toLowerCase 等方法都是在内部再创建一个新的String类对象。
String引用问题
String a = "hello";
String b = "hello";
String c = "he" + "llo";
String d = new String("hello");
String e = d.intern();
System.out.println(a == b);
System.out.println(a == c);
System.out.println(a == d);
System.out.println(a == e);
new String(“hello”) 会创建几个对象?
查看字节码:
0 new #2 <java/lang/String>
3 dup
4 ldc #3 <abc>
6 invokespecial #4 <java/lang/String.<init> : (Ljava/lang/String;)V>
9 pop
10 return
会创建2个对象:
- 通过new创建一个String对象。
- 类加载完后会在字符串常量池中创建
hello 字符串实例
new String(“abc”) + new String(“ABC”)会创建几个对象
0 new #2 <java/lang/StringBuilder>
3 dup
4 invokespecial #3 <java/lang/StringBuilder.<init> : ()V>
7 new #4 <java/lang/String>
10 dup
11 ldc #5 <abc>
13 invokespecial #6 <java/lang/String.<init> : (Ljava/lang/String;)V>
16 invokevirtual #7 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;>
19 new #4 <java/lang/String>
22 dup
23 ldc #8 <ABC>
25 invokespecial #6 <java/lang/String.<init> : (Ljava/lang/String;)V>
28 invokevirtual #7 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;>
31 invokevirtual #9 <java/lang/StringBuilder.toString : ()Ljava/lang/String;>
34 astore_1
35 return
会创建6个 对象:
- 对象1:new StringBuilder()
- 对象2:new String(“abc”)
- 对象3:常量池中的
abc 字符串实例 - 对象4:new String(“ABC”)
- 对象5:常量池中的
ABC 字符串实例 - 对象6:调用StringBuilder的toString()方法,会创建并返回一个String对象
注意:toString() 方法,不会在常量池中生成新的abcABC 对象,String类的本质是char数组。
|