Java编程思想8

第十三章:字符串
​ 由于字符串在我们开发中使用频率是相当高的,本章内容也主要介绍了一些关于字符串常用的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中,字符串操作应该还会更快一点。

 

posted @   就叫清风吧  阅读(22)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示