jvm字节码指令分析

2018-12-22  本文已影响0人  kevinfuture

java类:

public class TestModel {
    private Integer test = 1215201269;
    private Integer test1 = 90;
    private String stringTest = "haizeiwang";
    private Long aLongTest = 90890890L;
    private Float aFloatTest = 9099f;
    private String stringtest2 = "huoyingrenzhe";
    
}

这里我仅对<init>方法分析,也就是非静态的构造函数!
使用javap -verbose TestModel.class指令查看字节码指令:

public com.bj58.nodetest.contract.TestModel();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: ldc           #2                  // int 1215201269
         7: invokestatic  #3                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        10: putfield      #4                  // Field test:Ljava/lang/Integer;
        13: aload_0
        14: bipush        90
        16: invokestatic  #3                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        19: putfield      #5                  // Field test1:Ljava/lang/Integer;
        22: aload_0
        23: ldc           #6                  // String haizeiwang
        25: putfield      #7                  // Field stringTest:Ljava/lang/String;
        28: aload_0
        29: ldc2_w        #8                  // long 90890890l
        32: invokestatic  #10                 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
        35: putfield      #11                 // Field aLongTest:Ljava/lang/Long;
        38: aload_0
        39: ldc           #12                 // float 9099.0f
        41: invokestatic  #13                 // Method java/lang/Float.valueOf:(F)Ljava/lang/Float;
        44: putfield      #14                 // Field aFloatTest:Ljava/lang/Float;
        47: aload_0
        48: ldc           #15                 // String huoyingrenzhe
        50: putfield      #16                 // Field stringtest2:Ljava/lang/String;
        53: return
      LineNumberTable:
        line 11: 0
        line 12: 4
        line 13: 13
        line 14: 22
        line 15: 28
        line 16: 38
        line 17: 47
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      54     0  this   Lcom/bj58/nodetest/contract/TestModel;

好,线性表跟本地变量表也不分析

仅针对code,也就是字节码的指令进行分析。

一开始原始版本的分析,写在了excel中,如下:


111111.png

分析之后,发现自己分析的是错误的,根本对应不上,
看了下朋友推荐的文档,找到不同字节码指令的操作位,读取方式的不同
再根据这些索引值,获取类型信息,值域等等:
invoke开头的指令,包括invokespecial、invokestatic、invokeinterface、
invokevirtual、invokedynamic等,
获取的index运算方式为( index1 << 8 ) | index2 = index
最终所有index都指向常量池中的bytes所在的索引,由bytes生成具体值

图片1.png 图片2.png 图片3.png 图片4.png

正确的分析如下:

right.png

这样就能跟javap中的指令对应上了

上一篇下一篇

猜你喜欢

热点阅读