最近管理层要求把项目中所有的字符串“+”操作修改为StringBuilder/StringBuffer方式进行操作。以前在java5.0发布的时候好像看到过在这个新的编译器版本中对字符串的操作进行了优化,索性就彻底的研究下。
测试代码
String s1="********";
s1+="--------";
s1+="^^^^^^^^";
StringBuilder s2=new StringBuilder("********");
s2.append("--------");
s2.append("^^^^^^^^");
对应的class文件关键字节码
astore_1 [s1]//s1的是声明
3 new java.lang.StringBuilder [18]//JVM把s1优化为StringBuilder
6 dup
7 aload_1 [s1]
8 invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [20]
11 invokespecial java.lang.StringBuilder(java.lang.String) [26]
14 ldc <String "--------"> [29]
16 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [31]//执行“+”操作
19 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [35]//操作完成重新转化为String
22 astore_1 [s1]
23 new java.lang.StringBuilder [18]//再次把string转化为StringBuilder,重新执行上面的步骤
26 dup
27 aload_1 [s1]
28 invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [20]
31 invokespecial java.lang.StringBuilder(java.lang.String) [26]
34 ldc <String "^^^^^^^^"> [39]
36 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [31]
39 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [35]
42 astore_1 [s1]
43 new java.lang.StringBuilder [18]//最后转化为StringBuilder ,以备后面可能进行的字符串操作
46 dup
47 ldc <String "********"> [16]//下面是StringBuilder操作方式的字节码,可以看出没有进行String与StringBuilder的相互转化,直接append。
49 invokespecial java.lang.StringBuilder(java.lang.String) [26]
52 astore_2 [s2]
53 aload_2 [s2]
54 ldc <String "--------"> [29]
56 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [31]
59 pop
60 aload_2 [s2]
61 ldc <String "^^^^^^^^"> [39]
63 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [31]
这样基本可以得出结论:在5.0以后的版本,对于String直接进行"+"操作,java编译器会把其优化为StringBuilder后再进行append操作,然后进行来回的String<--->StringBuilder的转化,用StringBuilder的话可以会一直的append直道自己进行StringBuilder--->String的转化,因此在效率上String的“+”操作虽然简洁并比1.4以前的版本中的重新生成String对象进行操作有改进,但效率上仍然与StringBuilder有一定的差距,具体差距有多大,下面随便写了个测试代码
String str1="";
long start=System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
str1+="test";
}
str1+="--------";
long end=System.currentTimeMillis();
System.out.println("String耗时"+(end-start));
//StringBuilder
start=System.currentTimeMillis();
StringBuilder builder=new StringBuilder();
for (int i = 0; i < 50000; i++) {
builder.append("test");
}
builder.append("--------");
builder.toString();
end=System.currentTimeMillis();
System.out.println("StringBuilder耗时"+(end-start));
//随便测试下StringBuffer
start=System.currentTimeMillis();
StringBuffer buffer=new StringBuffer();
for (int i = 0; i < 50000; i++) {
buffer.append("test");
}
buffer.append("--------");
buffer.toString();
end=System.currentTimeMillis();
System.out.println("StringBuffer耗时"+(end-start));
结果:
String耗时7202
StringBuilder耗时16
StringBuffer耗时0
StringBuilder是线程非安全的,StringBuffer是线程安全的,按理来说StringBuilder应该比StringBuffer快才是,但结果有点出乎意料,可能是测试次数少的原因吧,过年了,先写这么多吧。
分享到:
相关推荐
以下是对Java 5.0新特性的详细解析: ### 1. 自动装箱与自动拆箱(AutoBoxing & UnBoxing) - **自动装箱**:是指将基本数据类型自动转换为对应的包装类型。例如,`int` 类型可以自动转换为 `Integer` 类型。这一...
Java 5.0对枚举类型进行了优化,使得枚举常量之间可以直接进行相等比较,无需使用`equals()`方法,这提高了性能和代码的简洁性。 以上就是Java JDK 5.0的一些核心特性,通过深入理解并熟练应用这些知识点,可以提升...
字符串池是Java虚拟机(JVM)为了优化字符串操作而设计的一个特性。它存储了所有的字符串字面量(即由双引号括起的字符串)。在JDK 5.0之前,字符串池是在常量池中实现的,而从JDK 5.0开始,字符串池被独立出来。当...
2. **枚举类型**:Java 5.0引入了枚举类型,用于表示一组固定的常量,相比传统的整数常量或字符串常量,枚举提供了更好的类型安全性和可读性。枚举可以有方法、字段,甚至可以实现接口。 3. **自动装箱/拆箱**:...
- `StringBuilder`:Java 5.0引入,可变字符串,单线程环境性能优于`StringBuffer`。 在实际编程中,需要根据具体需求选择合适的字符串处理类。例如,如果在循环中频繁修改字符串,`StringBuilder`或`StringBuffer`...
标题明确了文章的核心主题,即在Java环境中,对字符串连接操作的时间消耗进行测试和分析。这一主题对于理解不同字符串连接方式的性能优劣至关重要,尤其是当涉及到大量数据处理或高并发场景时,选择合适的字符串连接...
总之,理解数组和字符串的使用及其操作是Java编程的基础,熟练掌握这些知识点对于编写高效、可靠的程序至关重要。在实际项目中,开发者经常需要利用数组处理大量数据,利用字符串构建和处理文本信息,因此,深入学习...
6. **代码实现**:在Java或Kotlin代码中,可以创建一个函数来处理字符串转换,比如: ```java public Bitmap stringToBitmap(String encodedString) { byte[] decodedString = Base64.decode(encodedString, Base64...
《J2SE 5.0 第06章:常用类1》主要涵盖了Java标准版5.0中的核心类库,特别是对字符串(String)类的深入探讨。这一章的学习旨在帮助开发者掌握Java中字符串处理的基本技巧和高级特性,提高代码效率和可读性。 在Java...
Java API3,对应于Java 2 Platform Standard Edition 5.0(J2SE 5.0),是一个重要的里程碑,引入了许多新特性,改进了已有的API,并且对性能进行了优化。 1. **泛型**:Java 5.0引入了泛型,这是一种类型安全机制...
5. **字符串处理**:String类在Java中非常常用,试题可能会测试字符串的创建、比较、截取、替换、拼接等操作。 6. **数组与泛型**:数组是存储同类型数据的基本结构,泛型则为集合提供了类型安全的保证。试题可能...
枚举常用于表示一组常量,如方向、星期等,相比使用整数或字符串常量更安全、更易读。 3. **自动装箱与拆箱(Autoboxing and Unboxing)**:Java 5.0自动处理基本类型与对应的包装类之间的转换,简化了代码,如...
- **存储引擎**:SQL Anywhere 5.0采用了一种高效的存储机制,允许快速读取和写入数据,支持多种数据类型,包括数值、字符串、日期/时间等。 - **日志记录**:实时记录数据库操作,有助于故障恢复和数据备份。 3....
正则表达式是一种强大的文本处理工具,用于匹配、查找、替换和验证字符串模式。这个文本文件可能包含了一些用于验证QQ邮箱和电话号码格式的正则表达式示例。掌握正则表达式是Java开发者必备的技能之一,尤其是在...
Java JDK 1.5,也被称为Java 5.0,是Java开发工具包的一个重要版本,于2004年发布。这个版本引入了大量的新特性,优化和改进,极大地提升了Java编程的效率和灵活性。本API HTML文档是开发者学习和查阅Java 1.5 API的...
为了解决这个问题,Java 5.0引入了`StringBuilder`类,它提供了一个可变的字符序列,允许我们高效地进行字符串的拼接和修改。 `StringBuilder`类的核心优势在于它的可变性。与`String`不同,`StringBuilder`对象中...
这样,无论传入多少个字符串,编译器都会将它们视为一个字符串数组处理。 可变长参数的灵活性在于,它可以接受零个或多个参数,并且可以与固定参数一起使用,只要可变长参数是方法参数列表中的最后一个参数。这对于...
J2SE(Java 2 Standard Edition)5.0是Java平台的一个重要版本,它在2004年发布,引入了许多新的特性和改进,对Java开发者来说具有里程碑式的意义。 Java API文档是开发者的必备工具,它详尽地记录了Java类库的所有...
枚举类型可以有方法,可以实现接口,甚至可以有构造函数,这比传统的整数常量或字符串常量更安全,更具有表达力。 可变参数(varargs)是Java 5.0中的一个重要语法糖,它使得我们可以用数组的方式传递任意数量的...