Java字节码阅读初试

源代码

    public class QuickTest {

    	public static void main(String[] args) {
    		Animal dog=new Dog();
    		Animal cat=new Cat();
    		Dog myDog= (Dog) dog;
    	}

    }

    class Animal{}
    
    class Dog extends Animal{}
    
    class Cat extends Animal{}
    
- 说明: 一个类型转换的例子

反汇编

1. 命令: javac QuickTest.java && javap -c -v QuickTest.class

2. 说明: `//##` 为我所做注释, `//`为命令自动添加注释

3. 反汇编结果

        Last modified 2019-1-18; size 324 bytes         //## 最后一次修改时间
        MD5 checksum 04ed3e10fd0605777692526c73509243   //## MD5
        Compiled from "QuickTest.java"                  //## 原java文件
    public class QuickTest
        minor version: 0
        major version: 52                               //## class文件主版本号,52表示JDK8(表名需要JDK8以上才能执行该文件)
        flags: ACC_PUBLIC, ACC_SUPER                    //## 类的访问标志
    Constant pool:                                      //## 常量池
       #1 = Methodref          #7.#16         // java/lang/Object."<init>":()V      //## 方法符号引用
       #2 = Class              #17            // Dog                                //## 类或接口符号引用
       #3 = Methodref          #2.#16         // Dog."<init>":()V                   
       #4 = Class              #18            // Cat                                
       #5 = Methodref          #4.#16         // Cat."<init>":()V                   
       #6 = Class              #19            // QuickTest                          
       #7 = Class              #20            // java/lang/Object                   
       #8 = Utf8               <init>                                               //## 字符串: 方法名
       #9 = Utf8               ()V
      #10 = Utf8               Code
      #11 = Utf8               LineNumberTable                                      //## 字符串: 字节码行号与源代码行号对应关系
      #12 = Utf8               main
      #13 = Utf8               ([Ljava/lang/String;)V                               //## 字符串: 方法描述符: void(String[] args)
      #14 = Utf8               SourceFile                                           
      #15 = Utf8               QuickTest.java                                       
      #16 = NameAndType        #8:#9          // "<init>":()V                       //## 字段或方法的部分符号引用
      #17 = Utf8               Dog
      #18 = Utf8               Cat
      #19 = Utf8               QuickTest
      #20 = Utf8               java/lang/Object
    {
      public QuickTest();
        descriptor: ()V                         
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1                                        //## 一个栈帧, 本地变量表有一个变量, 参数大小为1(每一个方法编译时,编译器会自动添加一个this参数,表示引用当前对象)
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 6: 0
    
    public static void main(java.lang.String[]);
        descriptor: ([Ljava/lang/String;)V                                      //## 方法描述符: void (String[] args)
        flags: ACC_PUBLIC, ACC_STATIC                                           //## 方法访问修饰符public,static
        Code:
          stack=2, locals=4, args_size=1                                        //## 两个栈帧, 本地变量宝有4个变量(this, dog, cat, myDog), 参数大小为1(this)
            0: new           #2                  // class Dog                   //## 创建Dog对象并将其引用压入栈顶
            3: dup                                                              //## 复制栈顶Dog引用并压入栈顶
            4: invokespecial #3                  // Method Dog."<init>":()V     //## 调用栈顶Dog引用的<init>(类初始化方法)
            7: astore_1                                                         //## 将栈顶Dog引用存入本地变量表index=1位置
            8: new           #4                  // class Cat                   //## 创建Cat对象并将其引用压入栈顶
            11: dup                                                             //## 复制栈顶Cat引用并压入栈顶
            12: invokespecial #5                  // Method Cat."<init>":()V    //## 调用栈顶Cat引用的<init>(类初始化方法)
            15: astore_2                                                        //## 将栈顶Cat引用存入本地变量表index=2位置
            16: aload_1                                                         //## 将本地变量表第一个元素(Cat对象引用)压入栈顶
            17: checkcast     #2                  // class Dog                  //## 检查类型转换是否成功
            20: astore_3                                                        //## 存储栈顶元素到本地变量表index=3位置
            21: return                                                          //## 方法返回空
          LineNumberTable:                                                      //## 源码行号与字节码指令的对应关系
            line 9: 0
            line 10: 8
            line 11: 16
            line 12: 21
    }
    SourceFile: "QuickTest.java"                                                //## 源文件名

结语

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值