`
xiangshouxiyang
  • 浏览: 48847 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

java字符串拼接在编译时优化测试

阅读更多

为了验证编译器对于String相关代码的字节码优化,我简单的做了个测试:

jdk版本:1.7.0_51

 java 用例代码:

package com.rsp.shiro;

/**
 * Created by cd_huang on 2017/4/1.
 */
public class StringTest {
	public static String StaticString(){
		return "BBB";
	}
	public static String getString1(){
		return "AAA"+"BBB";
	}
	public static String getString2(){
		return new StringBuilder().append("AAA").append("BBB").toString();
	}
	public static String getString3(){
		return "AAA"+StaticString();
	}
	public static String getString4(){
		return new StringBuilder().append("AAA").append(StaticString()).toString();
	}
}

 命令行输入:C:\Users\hcd>javac c:\StringTest.java
生成StringTest.class文件。

命令行输入:C:\Users\hcd>javap -v c:\StringTest.class
生成java编译后的字节码指令。

Classfile /c:/StringTest.class
  Last modified 2017-4-1; size 721 bytes
  MD5 checksum 60b413955d7484157009f74a40848d59
  Compiled from "StringTest.java"
public class com.rsp.shiro.StringTest
  SourceFile: "StringTest.java"
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #11.#24        //  java/lang/Object."<init>":()V
   #2 = String             #25            //  BBB
   #3 = String             #26            //  AAABBB
   #4 = Class              #27            //  java/lang/StringBuilder
   #5 = Methodref          #4.#24         //  java/lang/StringBuilder."<init>":(
)V
   #6 = String             #28            //  AAA
   #7 = Methodref          #4.#29         //  java/lang/StringBuilder.append:(Lj
ava/lang/String;)Ljava/lang/StringBuilder;
   #8 = Methodref          #4.#30         //  java/lang/StringBuilder.toString:(
)Ljava/lang/String;
   #9 = Methodref          #10.#31        //  com/rsp/shiro/StringTest.StaticStr
ing:()Ljava/lang/String;
  #10 = Class              #32            //  com/rsp/shiro/StringTest
  #11 = Class              #33            //  java/lang/Object
  #12 = Utf8               <init>
  #13 = Utf8               ()V
  #14 = Utf8               Code
  #15 = Utf8               LineNumberTable
  #16 = Utf8               StaticString
  #17 = Utf8               ()Ljava/lang/String;
  #18 = Utf8               getString1
  #19 = Utf8               getString2
  #20 = Utf8               getString3
  #21 = Utf8               getString4
  #22 = Utf8               SourceFile
  #23 = Utf8               StringTest.java
  #24 = NameAndType        #12:#13        //  "<init>":()V
  #25 = Utf8               BBB
  #26 = Utf8               AAABBB
  #27 = Utf8               java/lang/StringBuilder
  #28 = Utf8               AAA
  #29 = NameAndType        #34:#35        //  append:(Ljava/lang/String;)Ljava/l
ang/StringBuilder;
  #30 = NameAndType        #36:#17        //  toString:()Ljava/lang/String;
  #31 = NameAndType        #16:#17        //  StaticString:()Ljava/lang/String;
  #32 = Utf8               com/rsp/shiro/StringTest
  #33 = Utf8               java/lang/Object
  #34 = Utf8               append
  #35 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #36 = Utf8               toString
{
  public com.rsp.shiro.StringTest();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>
":()V
         4: return
      LineNumberTable:
        line 6: 0

  public static java.lang.String StaticString();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: ldc           #2                  // String BBB
         2: areturn
      LineNumberTable:
        line 8: 0

  public static java.lang.String getString1();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: ldc           #3                  // String AAABBB
         2: areturn
      LineNumberTable:
        line 11: 0

  public static java.lang.String getString2();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=0, args_size=0
         0: new           #4                  // class java/lang/StringBuilder
         3: dup
         4: invokespecial #5                  // Method java/lang/StringBuilder.
"<init>":()V
         7: ldc           #6                  // String AAA
         9: invokevirtual #7                  // Method java/lang/StringBuilder.
append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        12: ldc           #2                  // String BBB
        14: invokevirtual #7                  // Method java/lang/StringBuilder.
append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        17: invokevirtual #8                  // Method java/lang/StringBuilder.
toString:()Ljava/lang/String;
        20: areturn
      LineNumberTable:
        line 14: 0

  public static java.lang.String getString3();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=0, args_size=0
         0: new           #4                  // class java/lang/StringBuilder
         3: dup
         4: invokespecial #5                  // Method java/lang/StringBuilder.
"<init>":()V
         7: ldc           #6                  // String AAA
         9: invokevirtual #7                  // Method java/lang/StringBuilder.
append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        12: invokestatic  #9                  // Method StaticString:()Ljava/lan
g/String;
        15: invokevirtual #7                  // Method java/lang/StringBuilder.
append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        18: invokevirtual #8                  // Method java/lang/StringBuilder.
toString:()Ljava/lang/String;
        21: areturn
      LineNumberTable:
        line 17: 0

  public static java.lang.String getString4();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=0, args_size=0
         0: new           #4                  // class java/lang/StringBuilder
         3: dup
         4: invokespecial #5                  // Method java/lang/StringBuilder.
"<init>":()V
         7: ldc           #6                  // String AAA
         9: invokevirtual #7                  // Method java/lang/StringBuilder.
append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        12: invokestatic  #9                  // Method StaticString:()Ljava/lan
g/String;
        15: invokevirtual #7                  // Method java/lang/StringBuilder.
append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        18: invokevirtual #8                  // Method java/lang/StringBuilder.
toString:()Ljava/lang/String;
        21: areturn
      LineNumberTable:
        line 20: 0
}

C:\Users\hcd>

 
可以看出来getString3() 方法和getString4()方法的字节码指令一摸一样,也就是编译器帮我们做了优化。
由于String对象时不可变对象,因此在对字符串进行拼接时,String对象总是会生成新的对象,所以其性能相对较差。
StringBuilder:一个非线程安全的字符串缓冲类,jdk1.5后出现。
所以,编译器在字符串对象拼接时,自动帮我们用StringBuilder实现了字符串拼接。



 

 

分享到:
评论

相关推荐

    java字符串拼接与性能分析详解

    Java字符串拼接是编程中常见的操作,特别是在处理大量数据或者构建复杂的输出时。然而,不同的字符串拼接方式在性能上存在显著差异。本篇文章将深入探讨Java中的字符串拼接技术,以及它们对程序效率的影响。 首先,...

    关于JDK8中的字符串拼接示例详解

    总结来说,JDK 8对字符串拼接进行了优化,当字符串拼接在编译时可确定时,编译器会自动转换为使用`StringBuilder`。然而,对于运行时动态拼接的情况,开发者仍需手动使用`StringBuilder`或`StringBuffer`以获得最佳...

    Java测试基础规范 Java测试基础规范

    避免在条件中赋值,添加默认子句到switch语句,避免嵌套赋值,谨慎比较浮点数,防止循环变量在循环内突变,避免参数和成员名称冲突,注意+运算符可能导致的字符串拼接混淆。 4. **面向对象编程**:避免隐藏继承的...

    android应用优化之String.zip_android_android性能优化_camp2dj

    2. **字符串拼接**:在循环中使用`+`操作符进行字符串拼接会创建大量中间对象,效率低下。应优先考虑使用`StringBuilder`或`StringBuffer`(多线程环境)来累积字符串,它们提供了append方法,避免了不必要的内存开销...

    java性能优化集锦

    2. **使用StringBuilder而非String拼接**:在循环中连接字符串时,StringBuilder比"+"操作符更高效。 3. **合理利用final关键字**:final可以提升方法内局部变量的访问速度,并有助于编译器进行优化。 4. **减少对象...

    java优化代码1.0版本.7z

    11. **使用StringBuffer代替String进行字符串拼接操作**,在多线程环境中,StringBuilder是线程不安全的,这时可以考虑使用StringBuffer。 以上只是Java优化的一部分内容,实际优化过程中还需要结合具体业务场景和...

    java代码优化编程共11页.pdf.zip

    2. **减少对象创建**:频繁的对象创建和销毁会增加垃圾回收的压力,可以考虑使用对象池、重用对象或者使用更轻量级的数据结构,如`StringBuilder`代替`String`进行字符串拼接。 3. **避免无谓的计算**:在循环中...

    java代码优化总结1.0版本.7z

    尽量减少嵌套循环,优化循环条件,使用StringBuilder而非+操作符进行字符串拼接。此外,使用预编译表达式(如PreparedStatement)代替动态SQL,可以提高数据库操作性能并防止SQL注入。 异常处理不应忽视。过度使用...

    JAVA代码优化[归类].pdf

    - 使用`StringBuilder`或`StringBuffer`代替`String`进行字符串拼接,尤其在循环中,前者提供了可变的特性,减少了对象生成。 - 使用`String.intern()`方法可以将字符串常量池中的引用返回,避免重复创建相同的...

    Java程序性能优化.doc

    在循环中拼接字符串时,`StringBuilder`和`StringBuffer`提供了更高效的追加操作,因为它们在内部维护了一个可变的字符数组,而字符串是不可变的,每次连接都会创建新的字符串对象。 2. 避免在循环内部创建对象。...

    java-jdk11版本jar包下载

    - **文本块(Text Blocks)**:这是一种新的字符串语法,用于表示多行文本,减少字符串拼接的繁琐和易错性。 - **ZGC(Z Garbage Collector)**:这是一个低延迟的垃圾收集器,适用于大内存应用,可以显著降低停顿...

    Java Platform SE 11.zip

    4. **文本块(Text Blocks)**:Java 11引入了文本块,一种多行字符串的表示方式,减少了字符串拼接的繁琐,尤其在处理大量文本数据时更加方便。 5. **增强的switch表达式**:switch语句在Java 11中得到了增强,...

    如何优化JAVA程序设计和编码,提高JAVA性能

    相比之下,`StringBuilder`或`StringBuffer`在拼接时不会生成新对象,因此更适合大量字符串操作。例如,避免使用`+`运算符连接字符串,而应该使用`StringBuilder.append()`方法。 ```java // 不推荐的方式 String ...

    性能优化:什么是性能优化

    例如,使用StringBuilder而非String进行字符串拼接,可以显著减少内存分配和提高性能。 3. 数据库交互: 对于依赖数据库的应用,优化SQL查询和索引是关键。减少数据库连接的开销,缓存常用数据,以及合理设计...

    JAVA jdk1.7 64位

    1. **语言增强**:Java 7引入了一些重要的语法改进,如自动资源管理(try-with-resources)使得资源关闭更加便捷,多 catch 语句允许一个 try 块捕获多种类型的异常,以及字符串在常量池中的拼接优化等。 2. **类型...

    阿里巴巴Java开发手册(嵩山版-2020.8).rar

    比如,提倡使用参数绑定而非字符串拼接来构造SQL,避免全表扫描,合理设计数据库表结构和索引,以及正确使用事务隔离级别等。 六、工程规约 工程规约关注项目结构、依赖管理、持续集成等方面。手册推荐使用Maven或...

    java常用词语例子以及解释

    `BufferedReader`和`StringBuffer`是处理文件读取和字符串拼接的常见工具。`BufferedReader`可以从文件中逐行读取文本,而`StringBuffer`则用于在多线程环境中安全地拼接字符串。例如: ```java BufferedReader in ...

    java初学者学习源代码day04.zip

    `CheckString`可能包含了一些字符串操作的实例,如检查字符串的空值、比较、拼接、查找子串等。 6. 所有的`.class`文件都是对应`.java`源代码文件编译后的结果,这意味着这个学习资料包含了从源代码到可执行代码的...

    j2html,Java到HTML生成器。享受类型安全的HTML生成。.zip

    这个库的核心理念是将Java的强类型特性与HTML的生成过程相结合,避免了传统字符串拼接导致的错误和不易维护的问题。通过j2html,开发者可以更高效、更可靠地构建动态网页应用。 **类型安全的HTML生成** 在传统的...

    阿-朗最新java面试题

    这种特殊性提供了线程安全和性能优化,因为字符串常用于拼接操作,不可变性使得它们可以在多线程环境下共享而无需担心数据同步问题。此外,Java的JVM为了提高效率,引入了常量池的概念。常量池存储了程序中的字符串...

Global site tag (gtag.js) - Google Analytics