为了验证编译器对于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,并且添加class到jvm
JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA...
通过实现本文提出的Java异常机制的静态编译算法,Open64编译器可以正确编译Java程序。 栈展开是被编译器和Java虚拟机普遍使用的一种实现异常处理机制的方法。本文针对传统的栈展开算法中存在的不足,提出了一种改进的...
JAVA反编译 JAVA反编译JAVA反编译
反编译工具jad简单用法 jad 是应用最广泛的java 反编译工具;... 这条指令将当前目录下的javatest.class反编译为javatest.java并保存在c:\\javasource目录里,其中的提示输出为中文,而不是Unicode代码。
一个小的编译和静态类型的 Lisp。 建造 依赖于 C++14 编译器,Java 和 Leiningen 在路径上。 make check 语言属性 按重要性的粗略排序: 分层设计。 小核。 (方案,沉,C) 渐进区域 -> GC。 (锈,艾达) 内存安全...
源实现参考网络资源;基于源实现解决了其重入问题。 语言环境:c++14 测试环境:在VS2019、ubuntu(wsl) g++(理论上支持c++14的都可以)
String类是字符串常量类,该类对象在建立后不能修改。Java编译器保证每个字符串常量都是String类对象。用双引号括住的一串字符即为字符串常量,比如“Welcome to Java!",在通过编译器编译后成为String对象。因而,...
java反编译 java 反编译 java反编译 java 反编译 java反编译 java 反编译 java反编译 java 反编译 java反编译 java 反编译
java反编译java反编译java反编译java反编译java反编译java反编译
包括java反编译工具jad.exe和使用手册.txt,与此同时还有反编译后的汉字unicode显示格式转换为字符格式的代码(绝对通过本人测试通过)
优点:本程序不需要用户手动敲击CMD命令,只需在图形界面上用鼠标点击即可方便地编译Java源程序,并可自定义class文件的存储位置。同时,在用户点击编译、运行等按钮时,会自动生成相应的CMD命令并通过对话框显示...
查找字符串需要结合pattern和matcher类使用 将指定的字符串形式的正则表达式编译成pattern对象
把.class文件编译成.java文件 打开xjad软件把.class文件直接拖进来,就可以编译成java源码了
java反编译软件java反编译软件java反编译软件
JSON官网上推荐的使用java解析json的类库,官网下载后的是未编译打包的java文件,这是我打包后的东东,使用时直接添加进Build path即可,简单实用……
可以将java编译后的class文件或者jar包反编译出来,看到编译前的代码
java的编译时多态和运行时多态,保证一看就会
Jdk 动态编译 Java 源码测试 Demo 通过 Jdk 工具类,直接将 Java 源码编译为 Class 字节码,并可加载为 Class 对象; 实例化后,可调用实例对象的方法 通过上面的实现,可以在线动态修改源码,并触发编译,加载到...
经测试可使用的反编译工具,将.class反编译成.java文件,使用起来非常方便