您现在的位置是:首页 >

Java扫描字节码 Java字节码深入解析

火烧 2022-11-08 01:59:30 1043
Java字节码深入解析   一 Java字节代码的组织形式  类文件{  OxCAFEBABE 小版本号 大版本号 常量池大小 常量池数组 访问控制标记 当前类信息 父类信息 实现的接口个数 实现的接

Java字节码深入解析  

  一 Java字节代码的组织形式

  类文件{

  OxCAFEBABE 小版本号 大版本号 常量池大小 常量池数组 访问控制标记 当前类信息 父类信息 实现的接口个数 实现的接口信息数组 域个数 域信息数组 方法个数 方法信息数组 属性个数 属性信息数组

  }

  二 查看方法 javap命令

  例子 有一个Java类Demo java

  public class Demo {    private String str ;    private String str ;    private int num ;    private int num ;    public static final String STATIC_DATA = hello world ;

  private void sayHello (){        System out println( this is method );    }    private void sayHello (){        System out println( this is method );    }    public void sayHello (){        System out println( this is method );    }}  通过jdk自带的反编译工具命令 javap 可以查看class文件的字节码信息

  D:>javap verbose Demo >> Demo txt  Demo txt

  Compiled from Demo java public class Demo extends java lang Object  SourceFile: Demo java   minor version:   major version:

  Constant pool:const # = class      # ;   //  Democonst # = Asciz     Demo;const # = class      # ;   //  java/lang/Objectconst # = Asciz     java/lang/Object;const # = Asciz     str ;const # = Asciz     Ljava/lang/String;;const # = Asciz     str ;const # = Asciz     num ;const # = Asciz     I;const # = Asciz   num ;const # = Asciz   STATIC_DATA;const # = Asciz   ConstantValue;const # = String  # ; //  hello worldconst # = Asciz   hello world;const # = Asciz   <init>;const # = Asciz   ()V;const # = Asciz   Code;const # = Method       # # ;   //  java/lang/Object <init> :()Vconst # = NameAndType    # :# ;//  <init> :()Vconst # = Asciz   LineNumberTable;const # = Asciz   LocalVariableTable;const # = Asciz   this;const # = Asciz   LDemo;;const # = Asciz   sayHello ;const # = Field   # # ;  //  java/lang/System out:Ljava/io/PrintStream;const # = class    # ; //  java/lang/Systemconst # = Asciz   java/lang/System;const # = NameAndType    # :# ;//  out:Ljava/io/PrintStream;const # = Asciz   out;const # = Asciz   Ljava/io/PrintStream;;const # = String  # ; //  this is method const # = Asciz   this is method ;const # = Method       # # ;  //  java/io/PrintStream println:(Ljava/lang/String;)Vconst # = class    # ; //  java/io/PrintStreamconst # = Asciz   java/io/PrintStream;const # = NameAndType    # :# ;//  println:(Ljava/lang/String;)Vconst # = Asciz   println;const # = Asciz   (Ljava/lang/String;)V;const # = Asciz   sayHello ;const # = String  # ; //  this is method const # = Asciz   this is method ;const # = Asciz   sayHello ;const # = String  # ; //  this is method const # = Asciz   this is method ;const # = Asciz   SourceFile;const # = Asciz   Demo java;

  {public static final java lang String STATIC_DATA;  Constant value: String hello worldpublic Demo();  Code:   Stack= Locals= Args_size=    :      aload_    :      invokespecial  # ; //Method java/lang/Object <init> :()V   :      return  LineNumberTable:   line :   LocalVariableTable:   Start  Length  Slot  Name   Signature                   this       LDemo;

  public void sayHello ();  Code:   Stack= Locals= Args_size=    :      getstatic   # ; //Field java/lang/System out:Ljava/io/PrintStream;   :      ldc   # ; //String this is method    :      invokevirtual  # ; //Method java/io/PrintStream println:(Ljava/lang/String;)V   :      return  LineNumberTable:   line :    line :   LocalVariableTable:   Start  Length  Slot  Name   Signature                   this       LDemo;}

  解析

   版本号 major version //java版本 jdk 显示的是 jdk 显示的是 jdk 显示的是 高版本能执行低版本的class文件

   常量池Constant pool

  Method 方法

  Field 字段

  String 字符串

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

Java扫描字节码 Java字节码深入解析

  NameAndType 变量名的类型

  Class 类

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

  三 检测代码的效率问题

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

  例子 一个Java类 TestString java

  <strong>public class TestString {    public String testString(String str String str ){       return str + str ;    }    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:   :      aload_    :      invokespecial  # ; //Method java/lang/Object <init> :()V   :      return

  public java lang String testString(java lang String java lang String);  Code:   :      new # ; //class java/lang/StringBuilder   :      dup   :      aload_    :      invokestatic    # ; //Method java/lang/String valueOf:(Ljava/lang/Object;)Ljava/lang/String;   :      invokespecial  # ; //Method java/lang/StringBuilder <init> :(Ljava/lang/String;)V   :     aload_    :    invokevirtual  # ; //Method java/lang/StringBuilder append:(Ljava/lang/String;)Ljava/lang/StringBuilder;   :    invokevirtual  # ; //Method java/lang/StringBuilder toString:()Ljava/lang/String;   :    areturn

  public java lang String testStringBuffer(java lang StringBuffer java lang String);  Code:   :      aload_    :      aload_    :      invokevirtual  # ; //Method java/lang/StringBuffer append:(Ljava/lang/String;)Ljava/lang/StringBuffer;   :      invokevirtual  # ; //Method java/lang/StringBuffer toString:()Ljava/lang/String;   :      areturn}  从上面编译后的字节码信息可以看出来 方法testString 调用了五个方法 new invokestatic invokespecial 和两个invokevirtual 而testStringBuffer 方法只调用了两个invokevirtual 方法 第一个方法比第二个方法多做了好多工作 其效率当然是要低的 而且我们从java/lang/StringBuilder append (Ljava/lang/String )Ljava/lang/StringBuilder

lishixinzhi/Article/program/Java/hx/201311/26098  
永远跟党走
  • 如果你觉得本站很棒,可以通过扫码支付打赏哦!

    • 微信收款码
    • 支付宝收款码