为什么80%的码农都做不了架构师?>>>   

我们经常会看到或者听到java代码要如何如何优化,这样写不对,那样写性能不高等等,可是我们如何去伪求真呢?就以 Java 代码性能优化总结文章中的内容例子,来求证一下吧

先热热身

String字符串拼接和StringBuffer一样吗

看看下面这段代码:


public class TestClass{public String incStringJoint(){String str = "a";String str1 = str + "b";return str1;}public String incStringBuffer(){StringBuffer str = new StringBuffer(3);str.append("a");str.append("b");return str.toString();  }}

抛开其他方面,这两段代码性能一样吗? 带着这个问题,我们去探索一番。

javac TestClass.java    //将java文件编译成class文件
javap -verbose TestClass.class  //反编译class文件

反编译结果:


{public TestClass();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1   // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 1: 0public java.lang.String incStringJoint(); // incStringJoint()方法执行情况descriptor: ()Ljava/lang/String;flags: ACC_PUBLICCode:stack=2, locals=3, args_size=10: ldc           #2   // String a2: astore_13: new           #3   // class java/lang/StringBuilder6: dup7: invokespecial #4   // Method java/lang/StringBuilder."<init>":()V10: aload_111: invokevirtual #5   // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;14: ldc           #6   // String b16: invokevirtual #5   // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;19: invokevirtual #7   // Method java/lang/StringBuilder.toString:()Ljava/lang/String;22: astore_223: aload_224: areturnLineNumberTable:      //反编译结果对应源码的行数line 4: 0line 5: 3line 6: 23public java.lang.String incStringBuffer(); // incStringBuffer()方法执行情况descriptor: ()Ljava/lang/String;flags: ACC_PUBLICCode:stack=3, locals=2, args_size=10: new           #8    // class java/lang/StringBuffer3: dup4: iconst_35: invokespecial #9    // Method java/lang/StringBuffer."<init>":(I)V8: astore_19: aload_110: ldc           #2    // String a12: invokevirtual #10   // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;15: pop16: aload_117: ldc           #6    // String b19: invokevirtual #10   // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;22: pop23: aload_124: invokevirtual #11   // Method java/lang/StringBuffer.toString:()Ljava/lang/String;27: areturnLineNumberTable:      //反编译结果对应源码的行数line 10: 0line 11: 9line 12: 16line 13: 23
}
SourceFile: "TestClass.java"

我们先大致看一下反编译的结果,可以发现其实String字符串拼接实质上是用StringBuilderappend方法实现,那么我们再看一下StringBufferStringBuilder的源码:可以发现,两个类的append方法调用的是同一个方法实现字符串拼接。

public AbstractStringBuilder append(String str) {if (str == null)return appendNull();int len = str.length();ensureCapacityInternal(count + len);str.getChars(0, len, value, count);count += len;return this;}

这里就有一个问题了,那为什么在字符串拼接的时候,要使用StringBuffer(线程安全)或者使用StringBuilder(线程不安全)呢?

现在我们修改一下代码:

public String incStringJoint(){String str = "a";String str1 = str + "b";String str2 = str1 + "c";return str2;}

多次拼接,看看结果怎么?


public java.lang.String incStringJoint();descriptor: ()Ljava/lang/String;flags: ACC_PUBLICCode:stack=2, locals=4, args_size=10: ldc           #2                  // String a2: astore_13: new           #3                  // class java/lang/StringBuilder6: dup7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V10: aload_111: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;14: ldc           #6                  // String b16: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;22: astore_223: new           #3                  // class java/lang/StringBuilder26: dup27: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V30: aload_231: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;34: ldc           #8                  // String c36: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;39: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;42: astore_343: aload_344: areturnLineNumberTable:line 4: 0line 5: 3line 6: 23line 7: 43

注意第3行第23行,new了两个StringBuilder。这就说明,利用String本身进行字符串拼接的时候,每拼接一次,就要new一个StringBuilder,再调用append方法。

new String()到底创建了几个对象

看下面代码:


public class TestClass{public String incString(){String str = "a";return str;}public String incNewString(){String str = new String("a");return str; }}

{public TestClass();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 1: 0public java.lang.String incString();descriptor: ()Ljava/lang/String;flags: ACC_PUBLICCode:stack=1, locals=2, args_size=10: ldc           #2                  // String a2: astore_13: aload_14: areturnLineNumberTable:line 20: 0line 21: 3public java.lang.String incNewString();descriptor: ()Ljava/lang/String;flags: ACC_PUBLICCode:stack=3, locals=2, args_size=10: new           #3                  // class java/lang/String3: dup4: ldc           #2                  // String a6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V9: astore_110: aload_111: areturnLineNumberTable:line 25: 0line 26: 10
}

持续更新

转载于:https://my.oschina.net/qnloft/blog/1501495

JAVA虚拟机——利用javap反编译class文件分析代码执行过程相关推荐

  1. 【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译 Dex 文件 | 分析 Dex 文件反编译结果 )

    文章目录 前言 一.打包 Jar 文件和 Dex 文件 1.示例代码 2.打包 Jar 文件 3.打包 Dex 文件 二.反编译 Dex 文件 三.分析 Dex 文件 1.Student 类相关信息 ...

  2. 命令行中使用javap反编译class文件

    由于自己在学习Java JVM相关知识的时候需要将java文件反编译成class文件进行性能分析,故将搜索到的方法整理如下: 步骤: 第一步:运行代码,生成.java文件 第二步:在当前路径下打开cm ...

  3. java 反编译 错误_IDEA中使用javap反编译工具,出现找不到类的错误,解决方法

    因为在看java编程思想,看到String章节,发现一个命令javap,可以反编译看汇编代码,进行代码的可行性优化. 自己心血来潮,在自己的IDEA中想试一试,不想使用cmd命令.正所谓,君子性非异也 ...

  4. java decompiler 3.11_Java反编译软件(DJ Java Decompiler)下载 v3.11.11.95官方版-第五资源...

    DJ Java Decompiler是一款十分实用的Java反编译软件,该软件可以将编译过的CLASS文件编译还原成为Java原始文件,并且不需要额外安装JVM(Java Virtual Machin ...

  5. java 反编译 class文件 jad eclipse乱码

    java 反编译 class文件 jad eclipse 编程 破解 工具 工具使用jad(还有joda,jd等工具) 1.使用jad反编译class文件,jad可以配置到eclipse中当做插件,直 ...

  6. myeclipse重新编译java,反编译class文件并重新编译的方法

    在没有.java源码的情况下,如果想修改一个.class文件.可以通过以下步骤实现: 修改前的class文件: 一.反编译.class文件成.java文件. 1.可以使用Java Decompiler ...

  7. 如何反编译apk文件并解析.class文件查看Java源代码

    如何反编译apk文件并解析.class文件查看Java源代码 前期工作:先准备好反编译需要用到的工具:下载链接. 1.把下载好的工具解压,得到下面这三个文件 2.配置环境变量到path(apktool ...

  8. JAD反编译class文件成java文件

    class文件是字节码文件,打开谁也看不懂,但是如果需要用里面代码的时候怎么办呢?其实通过JAD就可以进行反编译class文件成java文件 1.下载JAD JAD官网:https://varanec ...

  9. java 反编译class文件_用Java实现JVM第三章《解析class文件》

    解析class文件 案例介绍 本案例主要介绍通过java代码从class文件中解析:class文件.常量池.属性表: 作为类(或者接口)信息的载体,每个class文件都完整地定义了一个类.为了使jav ...

  10. apktool 反编译 java_APK文件使用ApkTool解包反编译和重新打包及签名

    前段使用一直使用一个手机APK软件,不过最近软件更新,出现了一个很讨厌的语音提示,于是想通过重新编译把语音提示去掉. [准备工作] 配置JAVA环境,到http://www.java.com/下载并进 ...

最新文章

  1. 五年程序员败在阿里三面,还是Java底层原理的问题啊!
  2. 权限管理(shiro框架)
  3. 如何让企业引起对网站运营优化的重视程度呢?
  4. 升级php7_PHP5.9 升级到PHP7 遇到的一些坑(phpfpm 图解)
  5. Font Rending 的 Hint 机制对排版的影响
  6. react native 原生模块桥接的简单说明
  7. android 九宫格封装,Android 九宫格的实现方法
  8. nfc sim android8,Android NFC相关资料之MifareClassic卡(读写)
  9. MathType requires a newer version of MT Extra等MathType问题的不兼容性解决方案
  10. 查看IIS进程所对应的应用程序池名称
  11. api wke_好用的wke浏览器代码,兼容chrome
  12. 运输问题基本解 最小元素法
  13. Scrapy 爬取链家租房价格信息
  14. PHP实现 鸡兔同笼的问题
  15. 数据库——MySQL——完整性约束
  16. Android adb: failed to install 0.apk: Failure [null]
  17. 《勇士传说》横版卷轴动作类游戏笔记目录
  18. c语言用循环函数求平方,用C语言程序三种循环语句分别编写程序,求1-100的平方值?...
  19. TCP/IP协议知识梳理
  20. 计算机系统运行太慢,如何解决电脑运行速度慢

热门文章

  1. flare3d_FLSL
  2. EVENT ADJUST_SCN 说明 [30681.1]
  3. 拦截导弹(CDQ分治,DP)
  4. ARC075 F.Mirrored
  5. 深圳市云瑶信息科技有限公司
  6. ubuntu 10.04 下驱动程序的hello word
  7. SharePoint 2010列表中新增的唯一性验证
  8. ROS-Academy-for-Beginners 替换自己的地图模型
  9. docker的源配置
  10. 移动端页面rem布局出现横向滚动条的修复