Java字节码深入解析

发表于:2011-12-06 09:30

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:周凡杨    来源:51Testing软件测试网采编

  解析:

  1、版本号 major version: 49 //java版本 jdk1.6显示的是50, jdk1.5显示的是49,jdk1.4显示的是58 , 高版本能执行低版本的class文件

  2、常量池Constant pool

  Method:方法

  Field:字段

  String:字符串

  Asciz:签名如<init>由jvm调用,其他是不能够去调用它的

  NameAndType:变量名的类型

  Class:类

  通过字节码,我们可以看到Demo类 继承于java.lang.Object,如果类中没有显式声明构造函数的话,编译器会插入一个缺省无参的构造函数(构造函数在JVM级别是显示成<init>的普通函数)。

  三:检测代码的效率问题

  学习Java的过程中,都会了解到字符串合并时要用到StringBuffer 来代替String,那下面就来通过Java字节码来验证两种方式的效率性。

  例子:一个Java类 TestString.java

  • <strong>public class TestString { 
  •     public String testString(String str1, String str2){ 
  •        return str1 + str2; 
  •     } 
  •     public String testStringBuffer(StringBuffer sb, String str){ 
  •        return sb.append(str).toString(); 
  •     } 
  •  </strong>
  •   javap –c TestString 后字节码信息:

  • Compiled from "TestString.java" 
  • public class TestString extends java.lang.Object{ 
  • public TestString(); 
  •   Code: 
  •    0:      aload_0 
  •    1:      invokespecial  #8//Method java/lang/Object."<init>":()V 
  •    4:      return 
  •   
  • public java.lang.String testString(java.lang.String, java.lang.String); 
  •   Code: 
  •    0:      new #16//class java/lang/StringBuilder 
  •    3:      dup 
  •    4:      aload_1 
  •    5:      invokestatic    #18//Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
  •    8:      invokespecial  #24//Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
  •    11:     aload_2 
  •    12:    invokevirtual  #27//Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
  •    15:    invokevirtual  #31//Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
  •    18:    areturn 
  •   
  • public java.lang.String testStringBuffer(java.lang.StringBuffer, java.lang.String); 
  •   Code: 
  •    0:      aload_1 
  •    1:      aload_2 
  •    2:      invokevirtual  #40//Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer; 
  •    5:      invokevirtual  #45//Method java/lang/StringBuffer.toString:()Ljava/lang/String; 
  •    8:      areturn 
  • }
  •   从上面编译后的字节码信息可以看出来,方法testString 调用了五个方法:new 、invokestatic 、invokespecial 和两个invokevirtual ; 而testStringBuffer 方法只调用了两个invokevirtual 方法。第一个方法比第二个方法多做了好多工作,其效率当然是要低的。而且我们从java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

      可以看出来其实对于String字符串合并,内部还是转化为StringBuilder的方法调用,这是因为String是长度不可变的,所以不如直接采用StringBuilder(与StringBuffer 长度都是可变的,只不过前者是非线程安全,后者是线程安全)进行字符串合并。

    22/2<12
    《2023软件测试行业现状调查报告》独家发布~

    关注51Testing

    联系我们

    快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

    法律顾问:上海兰迪律师事务所 项棋律师
    版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
    投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

    沪ICP备05003035号

    沪公网安备 31010102002173号