0%

字符串

字符串

String

String是一个final修饰的不可变类,其属性也是final的,底层使用char数组存储。

字符串拥有字符串常量池,对于String s = new String(“xyz”);

如果之前没有用过xyz的话,需要创建两个对象,一个是new String创建的对象,一个是常量xyz对象的内容创建的对象(常量池中一个,堆中一个)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
String s = new String("zxc");
}


public static void main(java.lang.String[]);
Code:
0: new #2 // class java/lang/String
3: dup
4: ldc #3 // String zxc
6: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: return
}

如果之前就存在xyz的话,只需要创建一个对象new String对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {
String ss = "zxc";
String s = new String("zxc");
}


public static void main(java.lang.String[]);
Code:
0: ldc #2 // String zxc
2: astore_1
3: new #3 // class java/lang/String
6: dup
7: ldc #2 // String zxc
9: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
12: astore_2
13: return
}

Process finished with exit code 0

字符串拼接

字符串拼接的字节码,在java8中进行字符串拼接时会编译为StringBuilder。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class TestString {
public static void main(String[] args) {
String s = null;
for(int i = 0;i<10;i++){
s = s + i;
}
}
}

public class com.zhanghe.study.stream.TestString {
public com.zhanghe.study.stream.TestString();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return

public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: iconst_0
3: istore_2
4: iload_2
5: bipush 10
7: if_icmpge 35
10: new #2 // class java/lang/StringBuilder
13: dup
14: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
17: aload_1
18: invokevirtual #4 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: iload_2
22: invokevirtual #5 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
25: invokevirtual #6 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
28: astore_1
29: iinc 2, 1
32: goto 4
35: return
}

intern方法

在使用字符串拼接之后生成的字符串如果调用intern()方法,就会返回该字符串所对应的常量池中字符串的地址值

1
2
3
4
5
6
7
8
9
10
11
12
String s1 = "aa";
String s2 = "bb";
String s3 = "aabb";
String s4 = s1+s2;
String s5 = "aa"+"bb";
String s6 = s4.intern();
System.out.println(s3 == s4);// false
System.out.println(s3 == s5);// true
System.out.println(s3 == s6);// true
System.out.println(s4 == s5);// false
System.out.println(s4 == s6);// false
System.out.println(s5 == s6);// true

其在jdk6中,当调用intern方法时,如果字符串常量池先前已经创建出该字符串对象,则返回池中的该字符串的引用,否则,将此字符串对象添加到字符串常量池中,并返回该字符串对象的引用

在jdk6+中,当调用intern方法时,如果字符串常量池先前已经创建出该字符串对象,则返回池中的该字符串的引用,否则,如果该字符串对象已经存在于java堆中,则将堆中此对象的引用添加到字符串常量池中,并且返回该引用;如果堆中不存在,则在池中创建该字符串并返回其引用

format格式化

1
String.format("%.2f", bound * 0.5)

内部使用的是Formatter

StringBuilder和StringBuffer

与StringBuffer相比,StringBuilder是线程不安全的,在单线程上操作比StringBuffer性能损耗小。

默认初始值大小为16,如果进行扩容的话,会进行数据内容的赋值,增加性能损耗,如果确定数据大小,可以指定大小

欢迎关注我的其它发布渠道