第十三章:字符串
由于字符串在我们开发中使用频率是相当高的,本章内容也主要介绍了一些关于字符串常用的API,需要注意的是String对象是不可变的,String类中每一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象,以包含修改后的字符串内容,而最初的String对象则丝毫未动。
重载“+”与StringBuilder
不可变性会带来一定的效率问题,为String对象重载的“+”操作符就是一个例子。重载的意义是,一个操作符在应用于特定的类时,被赋予了特殊的意义(用于String的“+”与“+=”是Java中仅有的两个重载过的操作符,而Java并不允程序员重载任何操作符,但C++允许程序员任意重载操作符)。操作符可以用来连接String:
public class Concatenation {
public static void main(String[] args) {
String mango = "mango";
String s = "abc" + mango + "def" + 47;
System.out.println(s);
}
}
// output: abcmangodef47
我们可以通过JDK自带的javap来反编译以上代码,命令如下:javap -c Concatenation.class
,这里的-c表示将要生成JVM字节码。
public class strings.Concatenation {
public strings.Concatenation();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String mango
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String abc
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: ldc #7 // String def
21: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: bipush 47
26: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
29: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
32: astore_2
33: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream;
36: aload_2
37: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
40: return
}
我们从生成后的字节码中可以看到,编译器自动引入了java.lang.StringBuilder类,虽然我们在源代码中并没有使用StringBuilder类,但是编译器却自主主张地使用了它,因为它更高效。
现在,也许你会觉得可以随意使用String对象,反正编译器会为你自动地优化性能,让我们更深入地看看编译器能为我们优化到什么程度。下面程序采用两种方式生成一个String:方法一使用了多个String对象,方法二在代码中使用了StringBuilder。
public class WitherStringBuilder {
/**
* 使用String进行字符串拼接
* @param fields 字符串数组
* @return 拼接后的字符串
*/
public String implicit(String[] fields) {
String result = "";
for (int i = 0; i < fields.length; i++) {
result += fields[i];
}
return result;
}
/**
* 使用StringBuilder进行字符串拼接
* @param fields 字符串数组
* @return 拼接后的字符串
*/
public String explicit(String[] fields) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < fields.length; i++) {
result.append(fields[i]);
}
return result.toString();
}
}
StringBuilder提供了丰富而全面的方法,包括insert()、repleace()、substring()甚至reverse(),但是最常用的还是append()和toString()。还有delete()方法,上面的例子中我们用它删除最后一个逗号与空格,以便添加右括号。
StringBuilder是Java SE5引入的,在这之前Java用的是StringBuffer。后者是线程安全的,因此开销也会大些,所以在Java SE5/6中,字符串操作应该还会更快一点。
标签:lang,Ljava,Java,String,思想,StringBuilder,编程,fields,java From: https://www.cnblogs.com/LvJinshuai/p/17003681.html