精华内容
下载资源
问答
  • javap:Javap的Web UI-源码

    2021-05-05 13:30:16
    javap pastebin用于查看一小段代码的字节码。 MPL 2.0许可。 先决条件 具有javap角色的PostgreSQL服务器, javap数据库的所有者 建造 开发人员: ./gradlew clean installShadowDist && ./gradlew :server:run --...
  • javap

    2018-04-01 17:35:17
    javap定义 javap是 Java class文件分解器,可以反编译(即对javac编译的文件进行反编译),也可以查看java编译器生成的字节码。用于分解class文件。 javap命令参数 C:\>javap -help 用法: javap <...

    javap定义
    javap是 Java class文件分解器,可以反编译(即对javac编译的文件进行反编译),也可以查看java编译器生成的字节码。用于分解class文件。
    javap命令参数

    C:\>javap -help
    用法: javap <options> <classes>
    其中, 可能的选项包括:
      -help  --help  -?        输出此用法消息
      -version                 版本信息
      -v  -verbose             输出附加信息
      -l                       输出行号和本地变量表
      -public                  仅显示公共类和成员
      -protected               显示受保护的/公共类和成员
      -package                 显示程序包/受保护的/公共类
                               和成员 (默认)
      -p  -private             显示所有类和成员
      -c                       对代码进行反汇编
      -s                       输出内部类型签名
      -sysinfo                 显示正在处理的类的
                               系统信息 (路径, 大小, 日期, MD5 散列)
      -constants               显示静态最终常量
      -classpath <path>        指定查找用户类文件的位置
      -bootclasspath <path>    覆盖引导类文件的位置**重点内容**
    javap -version
    C:\>javap -version
    1.7.0_71

    可以用 javap 查看编译后的 java class 文件字节码。
    如果你编译下面这个简单的类:

    package org.jvminternals;
    public class SimpleClass {
        public void sayHello() {
            System.out.println("Hello");
        }
    }

    运行下面的命令,就可以得到下面的结果输出:

    javap -v -p -s -sysinfo -constants classes/org/jvminternals/SimpleClass.class
    public class org.jvminternals.SimpleClass
      SourceFile: "SimpleClass.java"
      minor version: 0
      major version: 51
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #6.#17         //  java/lang/Object."<init>":()V
       #2 = Fieldref           #18.#19        //  java/lang/System.out:Ljava/io/PrintStream;
       #3 = String             #20            //  "Hello"
       #4 = Methodref          #21.#22        //  java/io/PrintStream.println:(Ljava/lang/String;)V
       #5 = Class              #23            //  org/jvminternals/SimpleClass
       #6 = Class              #24            //  java/lang/Object
       #7 = Utf8               <init>
       #8 = Utf8               ()V
       #9 = Utf8               Code
      #10 = Utf8               LineNumberTable
      #11 = Utf8               LocalVariableTable
      #12 = Utf8               this
      #13 = Utf8               Lorg/jvminternals/SimpleClass;
      #14 = Utf8               sayHello
      #15 = Utf8               SourceFile
      #16 = Utf8               SimpleClass.java
      #17 = NameAndType        #7:#8          //  "<init>":()V
      #18 = Class              #25            //  java/lang/System
      #19 = NameAndType        #26:#27        //  out:Ljava/io/PrintStream;
      #20 = Utf8               Hello
      #21 = Class              #28            //  java/io/PrintStream
      #22 = NameAndType        #29:#30        //  println:(Ljava/lang/String;)V
      #23 = Utf8               org/jvminternals/SimpleClass
      #24 = Utf8               java/lang/Object
      #25 = Utf8               java/lang/System
      #26 = Utf8               out
      #27 = Utf8               Ljava/io/PrintStream;
      #28 = Utf8               java/io/PrintStream
      #29 = Utf8               println
      #30 = Utf8               (Ljava/lang/String;)V
    {
      public org.jvminternals.SimpleClass();
        Signature: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
            0: aload_0
            1: invokespecial #1    // Method java/lang/Object."<init>":()V
            4: return
          LineNumberTable:
            line 3: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
              0      5      0    this   Lorg/jvminternals/SimpleClass;
    
      public void sayHello();
        Signature: ()V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=1, args_size=1
            0: getstatic      #2    // Field java/lang/System.out:Ljava/io/PrintStream;
            3: ldc            #3    // String "Hello"
            5: invokevirtual  #4    // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            8: return
          LineNumberTable:
            line 6: 0
            line 7: 8
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
              0      9      0    this   Lorg/jvminternals/SimpleClass;
    }

    这个 class 文件展示了三个主要部分:常量池、构造器方法和 sayHello 方法。
    常量池

    public class org.jvminternals.SimpleClass
      SourceFile: "SimpleClass.java"
      minor version: 0
      major version: 51
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #6.#17         //  java/lang/Object."<init>":()V
       #2 = Fieldref           #18.#19        //  java/lang/System.out:Ljava/io/PrintStream;
       #3 = String             #20            //  "Hello"
       #4 = Methodref          #21.#22        //  java/io/PrintStream.println:(Ljava/lang/String;)V
       #5 = Class              #23            //  org/jvminternals/SimpleClass
       #6 = Class              #24            //  java/lang/Object
       #7 = Utf8               <init>
       #8 = Utf8               ()V
       #9 = Utf8               Code
      #10 = Utf8               LineNumberTable
      #11 = Utf8               LocalVariableTable
      #12 = Utf8               this
      #13 = Utf8               Lorg/jvminternals/SimpleClass;
      #14 = Utf8               sayHello
      #15 = Utf8               SourceFile
      #16 = Utf8               SimpleClass.java
      #17 = NameAndType        #7:#8          //  "<init>":()V
      #18 = Class              #25            //  java/lang/System
      #19 = NameAndType        #26:#27        //  out:Ljava/io/PrintStream;
      #20 = Utf8               Hello
      #21 = Class              #28            //  java/io/PrintStream
      #22 = NameAndType        #29:#30        //  println:(Ljava/lang/String;)V
      #23 = Utf8               org/jvminternals/SimpleClass
      #24 = Utf8               java/lang/Object
      #25 = Utf8               java/lang/System
      #26 = Utf8               out
      #27 = Utf8               Ljava/io/PrintStream;
      #28 = Utf8               java/io/PrintStream
      #29 = Utf8               println
      #30 = Utf8               (Ljava/lang/String;)V
    {

    构造器方法

     public org.jvminternals.SimpleClass();
        Signature: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
            0: aload_0
            1: invokespecial #1    // Method java/lang/Object."<init>":()V
            4: return
          LineNumberTable:
            line 3: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
              0      5      0    this   Lorg/jvminternals/SimpleClass;

    sayHello 方法

    public void sayHello();
        Signature: ()V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=1, args_size=1
            0: getstatic      #2    // Field java/lang/System.out:Ljava/io/PrintStream;
            3: ldc            #3    // String "Hello"
            5: invokevirtual  #4    // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            8: return
          LineNumberTable:
            line 6: 0
            line 7: 8
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
              0      9      0    this   Lorg/jvminternals/SimpleClass;

    常量池:提供了通常由符号表提供的相同信息,详细描述见下文。
    方法:每一个方法包含四个区域,
    签名和访问标签
    字节码
    LineNumberTable:为调试器提供源码中的每一行对应的字节码信息。上面的例子中,Java 源码里的第 6 行与 sayHello
    函数字节码序号 0 相关,第 7 行与字节码序号 8 相关。
    LocalVariableTable:列出了所有栈帧中的局部变量。上面两个例子中,唯一的局部变量就是 this。

    展开全文
  • javap命令的使用技巧

    2020-08-27 14:56:04
    本篇文章给大家分享了关于JAVA中关于javap命令的使用技巧以及相关代码分享,有需要的朋友参考学习下。
  • 本篇文章主要介绍了如何为eclipse配置javap命令,在配置过程中会出现的小问题的解决方法,非常实用,需要的朋友可以参考下
  • javap-Tool:JAVA项目-源码

    2021-05-23 12:46:31
    Java javap工具的实现 javap打印出传递给它的类的包,受保护的字段以及公共字段和方法。
  • javaP:Java的想法-源码

    2021-04-20 23:10:00
    编程语言 Java的想法
  • javap使用总结

    2021-08-17 19:59:43
    三、javap主要参数的使用 四、解读javap解析得到的文件结构 五、小结 一、解析字节码的作用 通过反编译生成的字节码文件,我们可以深入的了解java代码的工作机制。但是,自己分析类文件结构太麻烦了!除了使用第...

    目录

    一、解析字节码的作用

    二、javac -g操作

    三、javap主要参数的使用

    四、解读javap解析得到的文件结构

    五、小结


    一、解析字节码的作用

    通过反编译生成的字节码文件,我们可以深入的了解java代码的工作机制。但是,自己分析类文件结构太麻烦了!除了使用第三方的jclasslib工具之外,oracle官方也提供了工具:javap。

    javap是jdk自带的反解析工具。它的作用就是根据class字节码文件,反解析出当前类对应的code区 (字节码指令)、局部变量表、异常表和代码行偏移量映射表、常量池等信息。

    通过局部变量表,我们可以查看局部变量的作用域范围、所在槽位等信息,甚至可以看到槽位复用等信息。

    二、javac -g操作

    解析字节码文件得到的信息中,有些信息(如局部变量表、指令和代码行偏移量映射表、常量池中方法的参数名称等等)需要在使用javac编译成class文件时,指定参数才能输出。

    比如,你直接javac xx.java,就不会在生成对应的局部变量表等信息,如果你使用javac -g xx.java就可以生成所有相关信息了。如果你使用的eclipse或IDEA,则默认情况下, eclipse、IDEA在编译时会帮你生成局部变量表、指令和代码行偏移量映射表等信息的。

    public class JavapTest {
        private int num;
        boolean flag;
        protected char gender;
        public String info;
    
        public static final int COUNTS = 1;
    
        static {
            String url = "www.atguigu.com";
        }
    
        {
            info = "java";
        }
    
        public JavapTest() {
    
        }
    
        private JavapTest(boolean flag) {
            this.flag = flag;
        }
    
        private void methodPrivate() {
    
        }
    
        int getNum(int i) {
            return num + i;
        }
    
        protected char showGender() {
            return gender;
        }
    
        public void showInfo() {
            int i = 10;
            System.out.println(info + i);
        }
    }

    我们使用javac JavapTest.java对其进行编译,生成一个字节码文件,并放到一个文件夹中;

    然后我们加上-g参数再编译一次:javac -g JavapTest.java 生成class字节码文件之后,我们发现两个字节码文件的大小不一样,带上-g参数的class文件更大一些,说明其内容更丰富。

    下面我们通过javap将两个class文件反解析,看下多出来的信息是哪一部分。

    #操作不带-g参数的字节码文件
    javap -v JavapTest.class > 1.txt
    #操作带-g参数的字节码文件
    javap -v JavapTest.class > 2.txt

    对比一下1.txt和2.txt,我们发现,带上-g参数的字节码文件反解析之后多了一些局部变量表相关信息,大家可以自己比对一下:

    三、javap主要参数的使用

    一般常用的是-v -l -c三个选项。

    • javap -l :会输出行号和本地变量表信息;
    • javap -c :会对当前class字节码进行反编译生成汇编代码;
    • javap -v: class字节码文件中除了包-c参数包含的内容外,还会输出行号、局部变量表信息、常量池等信息;

    ① javap -public JavapTest.class :显示公共信息

    Compiled from "JavapTest.java"
    public class com.wsh.jvm.test.JavapTest {
      public java.lang.String info;
      public static final int COUNTS;
      public com.wsh.jvm.test.JavapTest();
      public void showInfo();
    }

    ② javap -protected JavapTest.class :显示受保护的/公共类和成员

    Compiled from "JavapTest.java"
    public class com.wsh.jvm.test.JavapTest {
      protected char gender;
      public java.lang.String info;
      public static final int COUNTS;
      public com.wsh.jvm.test.JavapTest();
      protected char showGender();
      public void showInfo();
    }

    ③ javap -p(或-private)JavapTest.class :显示所有类和成员(大于private的)

    Compiled from "JavapTest.java"
    public class com.wsh.jvm.test.JavapTest {
      private int num;
      boolean flag;
      protected char gender;
      public java.lang.String info;
      public static final int COUNTS;
      public com.wsh.jvm.test.JavapTest();
      private com.wsh.jvm.test.JavapTest(boolean);
      private void methodPrivate();
      int getNum(int);
      protected char showGender();
      public void showInfo();
      static {};
    }

    ④ javap -package JavapTest.class :显示程序包/受保护的/公共类和成员(默认),非私有的信息

    Compiled from "JavapTest.java"
    public class com.wsh.jvm.test.JavapTest {
      boolean flag;
      protected char gender;
      public java.lang.String info;
      public static final int COUNTS;
      public com.wsh.jvm.test.JavapTest();
      int getNum(int);
      protected char showGender();
      public void showInfo();
      static {};
    }

    ⑤ javap -sysinfo JavapTest.class :显示正在处理的类的系统信息(路径,大小,日期,MD5 散列,源文件名)

    Classfile /D:/workspace/rocketmq-demo/src/main/java/com/wsh/jvm/test/JavapTest.class
      Last modified 2021-8-15; size 1356 bytes
      MD5 checksum d69c979c54e42bf85f47cd5fa93ff4cc
      Compiled from "JavapTest.java"
    public class com.wsh.jvm.test.JavapTest {
      boolean flag;
      protected char gender;
      public java.lang.String info;
      public static final int COUNTS;
      public com.wsh.jvm.test.JavapTest();
      int getNum(int);
      protected char showGender();
      public void showInfo();
      static {};
    }

    ⑥ javap -constants JavapTest.class:与前面命令的主要区别,常量值会显示出来COUNTS = 1;

    Compiled from "JavapTest.java"
    public class com.wsh.jvm.test.JavapTest {
      boolean flag;
      protected char gender;
      public java.lang.String info;
      public static final int COUNTS = 1;
      public com.wsh.jvm.test.JavapTest();
      int getNum(int);
      protected char showGender();
      public void showInfo();
      static {};
    }

    ⑦、 javap -s JavapTest.class:输出内部类型签名(描述符)

    Compiled from "JavapTest.java"
    public class com.wsh.jvm.test.JavapTest {
      boolean flag;
        descriptor: Z
      protected char gender;
        descriptor: C
      public java.lang.String info;
        descriptor: Ljava/lang/String;
      public static final int COUNTS;
        descriptor: I
      public com.wsh.jvm.test.JavapTest();
        descriptor: ()V
    
      int getNum(int);
        descriptor: (I)I
    
      protected char showGender();
        descriptor: ()C
    
      public void showInfo();
        descriptor: ()V
    
      static {};
        descriptor: ()V
    }

    ⑧、javap -l JavapTest.class:输出行号和本地变量表

    public class com.wsh.jvm.test.JavapTest {
      boolean flag;
    
      protected char gender;
    
      public java.lang.String info;
    
      public static final int COUNTS;
    
      public com.wsh.jvm.test.JavapTest();
        LineNumberTable:
          line 19: 0
          line 16: 4
          line 21: 10
        LocalVariableTable:
          Start  Length  Slot  Name   Signature
              0      11     0  this   Lcom/wsh/jvm/test/JavapTest;
    
      int getNum(int);
        LineNumberTable:
          line 32: 0
        LocalVariableTable:
          Start  Length  Slot  Name   Signature
              0       7     0  this   Lcom/wsh/jvm/test/JavapTest;
              0       7     1     i   I
    
      protected char showGender();
        LineNumberTable:
          line 36: 0
        LocalVariableTable:
          Start  Length  Slot  Name   Signature
              0       5     0  this   Lcom/wsh/jvm/test/JavapTest;
    
      public void showInfo();
        LineNumberTable:
          line 40: 0
          line 41: 3
          line 42: 30
        LocalVariableTable:
          Start  Length  Slot  Name   Signature
              0      31     0  this   Lcom/wsh/jvm/test/JavapTest;
              3      28     1     i   I
    
      static {};
        LineNumberTable:
          line 12: 0
          line 13: 3
        LocalVariableTable:
          Start  Length  Slot  Name   Signature
    }

    ⑨、javap -c JavapTest.class:对代码进行反汇编

    Compiled from "JavapTest.java"
    public class com.wsh.jvm.test.JavapTest {
      boolean flag;
    
      protected char gender;
    
      public java.lang.String info;
    
      public static final int COUNTS;
    
      public com.wsh.jvm.test.JavapTest();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: aload_0
           5: ldc           #2                  // String java
           7: putfield      #3                  // Field info:Ljava/lang/String;
          10: return
    
      int getNum(int);
        Code:
           0: aload_0
           1: getfield      #5                  // Field num:I
           4: iload_1
           5: iadd
           6: ireturn
    
      protected char showGender();
        Code:
           0: aload_0
           1: getfield      #6                  // Field gender:C
           4: ireturn
    
      public void showInfo();
        Code:
           0: bipush        10
           2: istore_1
           3: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
           6: new           #8                  // class java/lang/StringBuilder
           9: dup
          10: invokespecial #9                  // Method java/lang/StringBuilder."<init>":()V
          13: aload_0
          14: getfield      #3                  // Field info:Ljava/lang/String;
          17: invokevirtual #10                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          20: iload_1
          21: invokevirtual #11                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
          24: invokevirtual #12                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          27: invokevirtual #13                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          30: return
    
      static {};
        Code:
           0: ldc           #14                 // String www.atguigu.com
           2: astore_0
           3: return
    }

    ⑩、 javap -v(-verbose) JavapTest.class:输出附加信息(包括行号、本地变量表、反汇编等详细信息),-v是最全的

    Classfile /D:/workspace/rocketmq-demo/src/main/java/com/wsh/jvm/test/JavapTest.class
      Last modified 2021-8-15; size 1356 bytes
      MD5 checksum d69c979c54e42bf85f47cd5fa93ff4cc
      Compiled from "JavapTest.java"
    public class com.wsh.jvm.test.JavapTest
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #16.#46        // java/lang/Object."<init>":()V
       #2 = String             #47            // java
       #3 = Fieldref           #15.#48        // com/wsh/jvm/test/JavapTest.info:Ljava/lang/String;
       #4 = Fieldref           #15.#49        // com/wsh/jvm/test/JavapTest.flag:Z
       #5 = Fieldref           #15.#50        // com/wsh/jvm/test/JavapTest.num:I
       #6 = Fieldref           #15.#51        // com/wsh/jvm/test/JavapTest.gender:C
       #7 = Fieldref           #52.#53        // java/lang/System.out:Ljava/io/PrintStream;
       #8 = Class              #54            // java/lang/StringBuilder
       #9 = Methodref          #8.#46         // java/lang/StringBuilder."<init>":()V
      #10 = Methodref          #8.#55         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      #11 = Methodref          #8.#56         // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      #12 = Methodref          #8.#57         // java/lang/StringBuilder.toString:()Ljava/lang/String;
      #13 = Methodref          #58.#59        // java/io/PrintStream.println:(Ljava/lang/String;)V
      #14 = String             #60            // www.atguigu.com
      #15 = Class              #61            // com/wsh/jvm/test/JavapTest
      #16 = Class              #62            // java/lang/Object
      #17 = Utf8               num
      #18 = Utf8               I
      #19 = Utf8               flag
      #20 = Utf8               Z
      #21 = Utf8               gender
      #22 = Utf8               C
      #23 = Utf8               info
      #24 = Utf8               Ljava/lang/String;
      #25 = Utf8               COUNTS
      #26 = Utf8               ConstantValue
      #27 = Integer            1
      #28 = Utf8               <init>
      #29 = Utf8               ()V
      #30 = Utf8               Code
      #31 = Utf8               LineNumberTable
      #32 = Utf8               LocalVariableTable
      #33 = Utf8               this
      #34 = Utf8               Lcom/wsh/jvm/test/JavapTest;
      #35 = Utf8               (Z)V
      #36 = Utf8               methodPrivate
      #37 = Utf8               getNum
      #38 = Utf8               (I)I
      #39 = Utf8               i
      #40 = Utf8               showGender
      #41 = Utf8               ()C
      #42 = Utf8               showInfo
      #43 = Utf8               <clinit>
      #44 = Utf8               SourceFile
      #45 = Utf8               JavapTest.java
      #46 = NameAndType        #28:#29        // "<init>":()V
      #47 = Utf8               java
      #48 = NameAndType        #23:#24        // info:Ljava/lang/String;
      #49 = NameAndType        #19:#20        // flag:Z
      #50 = NameAndType        #17:#18        // num:I
      #51 = NameAndType        #21:#22        // gender:C
      #52 = Class              #63            // java/lang/System
      #53 = NameAndType        #64:#65        // out:Ljava/io/PrintStream;
      #54 = Utf8               java/lang/StringBuilder
      #55 = NameAndType        #66:#67        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      #56 = NameAndType        #66:#68        // append:(I)Ljava/lang/StringBuilder;
      #57 = NameAndType        #69:#70        // toString:()Ljava/lang/String;
      #58 = Class              #71            // java/io/PrintStream
      #59 = NameAndType        #72:#73        // println:(Ljava/lang/String;)V
      #60 = Utf8               www.atguigu.com
      #61 = Utf8               com/wsh/jvm/test/JavapTest
      #62 = Utf8               java/lang/Object
      #63 = Utf8               java/lang/System
      #64 = Utf8               out
      #65 = Utf8               Ljava/io/PrintStream;
      #66 = Utf8               append
      #67 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
      #68 = Utf8               (I)Ljava/lang/StringBuilder;
      #69 = Utf8               toString
      #70 = Utf8               ()Ljava/lang/String;
      #71 = Utf8               java/io/PrintStream
      #72 = Utf8               println
      #73 = Utf8               (Ljava/lang/String;)V
    {
      boolean flag;
        descriptor: Z
        flags:
    
      protected char gender;
        descriptor: C
        flags: ACC_PROTECTED
    
      public java.lang.String info;
        descriptor: Ljava/lang/String;
        flags: ACC_PUBLIC
    
      public static final int COUNTS;
        descriptor: I
        flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
        ConstantValue: int 1
    
      public com.wsh.jvm.test.JavapTest();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: aload_0
             5: ldc           #2                  // String java
             7: putfield      #3                  // Field info:Ljava/lang/String;
            10: return
          LineNumberTable:
            line 19: 0
            line 16: 4
            line 21: 10
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      11     0  this   Lcom/wsh/jvm/test/JavapTest;
    
      int getNum(int);
        descriptor: (I)I
        flags:
        Code:
          stack=2, locals=2, args_size=2
             0: aload_0
             1: getfield      #5                  // Field num:I
             4: iload_1
             5: iadd
             6: ireturn
          LineNumberTable:
            line 32: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       7     0  this   Lcom/wsh/jvm/test/JavapTest;
                0       7     1     i   I
    
      protected char showGender();
        descriptor: ()C
        flags: ACC_PROTECTED
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: getfield      #6                  // Field gender:C
             4: ireturn
          LineNumberTable:
            line 36: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   Lcom/wsh/jvm/test/JavapTest;
    
      public void showInfo();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=3, locals=2, args_size=1
             0: bipush        10
             2: istore_1
             3: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
             6: new           #8                  // class java/lang/StringBuilder
             9: dup
            10: invokespecial #9                  // Method java/lang/StringBuilder."<init>":()V
            13: aload_0
            14: getfield      #3                  // Field info:Ljava/lang/String;
            17: invokevirtual #10                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
            20: iload_1
            21: invokevirtual #11                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
            24: invokevirtual #12                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
            27: invokevirtual #13                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            30: return
          LineNumberTable:
            line 40: 0
            line 41: 3
            line 42: 30
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      31     0  this   Lcom/wsh/jvm/test/JavapTest;
                3      28     1     i   I
    
      static {};
        descriptor: ()V
        flags: ACC_STATIC
        Code:
          stack=1, locals=1, args_size=0
             0: ldc           #14                 // String www.atguigu.com
             2: astore_0
             3: return
          LineNumberTable:
            line 12: 0
            line 13: 3
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
    }
    SourceFile: "JavapTest.java"

    四、解读javap解析得到的文件结构

    我们使用如下参数输出 JavapTest文件的字节码信息:javap -v -p JavapTest.class > JavapTest.txt,具体解析如下注释:

    Classfile /D:/workspace/rocketmq-demo/src/main/java/com/wsh/jvm/test/JavapTest.class  	//字节码文件所属的文件路径
      Last modified 2021-8-15; size 1356 bytes												//最后修改时间,字节码文件的大小
      MD5 checksum d69c979c54e42bf85f47cd5fa93ff4cc											//MD5散列值
      Compiled from "JavapTest.java"														//源文件名称
    public class com.wsh.jvm.test.JavapTest													
      minor version: 0																		//副版本
      major version: 52																		//主版本
      flags: ACC_PUBLIC, ACC_SUPER															//访问标识
    Constant pool:																			//常量池
       #1 = Methodref          #16.#46        // java/lang/Object."<init>":()V
       #2 = String             #47            // java
       #3 = Fieldref           #15.#48        // com/wsh/jvm/test/JavapTest.info:Ljava/lang/String;
       #4 = Fieldref           #15.#49        // com/wsh/jvm/test/JavapTest.flag:Z
       #5 = Fieldref           #15.#50        // com/wsh/jvm/test/JavapTest.num:I
       #6 = Fieldref           #15.#51        // com/wsh/jvm/test/JavapTest.gender:C
       #7 = Fieldref           #52.#53        // java/lang/System.out:Ljava/io/PrintStream;
       #8 = Class              #54            // java/lang/StringBuilder
       #9 = Methodref          #8.#46         // java/lang/StringBuilder."<init>":()V
      #10 = Methodref          #8.#55         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      #11 = Methodref          #8.#56         // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      #12 = Methodref          #8.#57         // java/lang/StringBuilder.toString:()Ljava/lang/String;
      #13 = Methodref          #58.#59        // java/io/PrintStream.println:(Ljava/lang/String;)V
      #14 = String             #60            // www.atguigu.com
      #15 = Class              #61            // com/wsh/jvm/test/JavapTest
      #16 = Class              #62            // java/lang/Object
      #17 = Utf8               num
      #18 = Utf8               I
      #19 = Utf8               flag
      #20 = Utf8               Z
      #21 = Utf8               gender
      #22 = Utf8               C
      #23 = Utf8               info
      #24 = Utf8               Ljava/lang/String;
      #25 = Utf8               COUNTS
      #26 = Utf8               ConstantValue
      #27 = Integer            1
      #28 = Utf8               <init>
      #29 = Utf8               ()V
      #30 = Utf8               Code
      #31 = Utf8               LineNumberTable
      #32 = Utf8               LocalVariableTable
      #33 = Utf8               this
      #34 = Utf8               Lcom/wsh/jvm/test/JavapTest;
      #35 = Utf8               (Z)V
      #36 = Utf8               methodPrivate
      #37 = Utf8               getNum
      #38 = Utf8               (I)I
      #39 = Utf8               i
      #40 = Utf8               showGender
      #41 = Utf8               ()C
      #42 = Utf8               showInfo
      #43 = Utf8               <clinit>
      #44 = Utf8               SourceFile
      #45 = Utf8               JavapTest.java
      #46 = NameAndType        #28:#29        // "<init>":()V
      #47 = Utf8               java
      #48 = NameAndType        #23:#24        // info:Ljava/lang/String;
      #49 = NameAndType        #19:#20        // flag:Z
      #50 = NameAndType        #17:#18        // num:I
      #51 = NameAndType        #21:#22        // gender:C
      #52 = Class              #63            // java/lang/System
      #53 = NameAndType        #64:#65        // out:Ljava/io/PrintStream;
      #54 = Utf8               java/lang/StringBuilder
      #55 = NameAndType        #66:#67        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      #56 = NameAndType        #66:#68        // append:(I)Ljava/lang/StringBuilder;
      #57 = NameAndType        #69:#70        // toString:()Ljava/lang/String;
      #58 = Class              #71            // java/io/PrintStream
      #59 = NameAndType        #72:#73        // println:(Ljava/lang/String;)V
      #60 = Utf8               www.atguigu.com
      #61 = Utf8               com/wsh/jvm/test/JavapTest
      #62 = Utf8               java/lang/Object
      #63 = Utf8               java/lang/System
      #64 = Utf8               out
      #65 = Utf8               Ljava/io/PrintStream;
      #66 = Utf8               append
      #67 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
      #68 = Utf8               (I)Ljava/lang/StringBuilder;
      #69 = Utf8               toString
      #70 = Utf8               ()Ljava/lang/String;
      #71 = Utf8               java/io/PrintStream
      #72 = Utf8               println
      #73 = Utf8               (Ljava/lang/String;)V
    ################################################字段表集合的信息####################################################### 
    {                                                              
      private int num;												 	//字段名
        descriptor: I													//字段描述符:字段类型
        flags: ACC_PRIVATE												//字段的访问标识
    
      boolean flag;
        descriptor: Z
        flags:
    
      protected char gender;
        descriptor: C
        flags: ACC_PROTECTED
    
      public java.lang.String info;
        descriptor: Ljava/lang/String;
        flags: ACC_PUBLIC
    
      public static final int COUNTS;
        descriptor: I
        flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
        ConstantValue: int 1											//常量字段的属性:ConstantValue
    
    #################################################方法表集合的信息######################################################
      public com.wsh.jvm.test.JavapTest();								//构造器1的信息							
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: aload_0
             5: ldc           #2                  // String java
             7: putfield      #3                  // Field info:Ljava/lang/String;
            10: return
          LineNumberTable:
            line 19: 0
            line 16: 4
            line 21: 10
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      11     0  this   Lcom/wsh/jvm/test/JavapTest;
    
      private com.wsh.jvm.test.JavapTest(boolean);						//构造器2的信息
        descriptor: (Z)V
        flags: ACC_PRIVATE
        Code:
          stack=2, locals=2, args_size=2
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: aload_0
             5: ldc           #2                  // String java
             7: putfield      #3                  // Field info:Ljava/lang/String;
            10: aload_0
            11: iload_1
            12: putfield      #4                  // Field flag:Z
            15: return
          LineNumberTable:
            line 23: 0
            line 16: 4
            line 24: 10
            line 25: 15
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      16     0  this   Lcom/wsh/jvm/test/JavapTest;
                0      16     1  flag   Z
    
      private void methodPrivate();
        descriptor: ()V
        flags: ACC_PRIVATE
        Code:
          stack=0, locals=1, args_size=1
             0: return
          LineNumberTable:
            line 29: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       1     0  this   Lcom/wsh/jvm/test/JavapTest;
    
      int getNum(int);
        descriptor: (I)I
        flags:
        Code:
          stack=2, locals=2, args_size=2
             0: aload_0
             1: getfield      #5                  // Field num:I
             4: iload_1
             5: iadd
             6: ireturn
          LineNumberTable:
            line 32: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       7     0  this   Lcom/wsh/jvm/test/JavapTest;
                0       7     1     i   I
    
      protected char showGender();
        descriptor: ()C
        flags: ACC_PROTECTED
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: getfield      #6                  // Field gender:C
             4: ireturn
          LineNumberTable:
            line 36: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   Lcom/wsh/jvm/test/JavapTest;
    
      public void showInfo();												
        descriptor: ()V														//方法描述符:方法的形参列表、返回值类型
        flags: ACC_PUBLIC													//方法访问标识
        Code:																//方法的Code属性
          stack=3, locals=2, args_size=1									//stack:操作数栈的最大深度、locals:局部变量表的长度、args_size:方法接收参数的个数(this参数)
       /偏移量:操作码       操作数
    		 0: bipush        10
             2: istore_1
             3: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
             6: new           #8                  // class java/lang/StringBuilder
             9: dup
            10: invokespecial #9                  // Method java/lang/StringBuilder."<init>":()V
            13: aload_0
            14: getfield      #3                  // Field info:Ljava/lang/String;
            17: invokevirtual #10                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
            20: iload_1
            21: invokevirtual #11                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
            24: invokevirtual #12                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
            27: invokevirtual #13                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            30: return
          //行号表:指明字节码指令的偏移量与Java源代码中代码的行号的一一对应关系
    	  LineNumberTable:
            line 40: 0
            line 41: 3
            line 42: 30
    	  //局部变量表:描述内部局部变量的相关信息
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      31     0  this   Lcom/wsh/jvm/test/JavapTest;
                3      28     1     i   I
    
      static {};												//静态代码块相关信息							
        descriptor: ()V
        flags: ACC_STATIC
        Code:
          stack=1, locals=1, args_size=0
             0: ldc           #14                 // String www.atguigu.com
             2: astore_0
             3: return
          LineNumberTable:
            line 12: 0
            line 13: 3
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
    }
    SourceFile: "JavapTest.java"	

    五、小结

    1. 通过javap命令可以查看一个java类反汇编得到的Class文件版本号、常量池、访问标识、变量表、指令代码行号表等信息,但是注意,javap命令并不会显示类索引、父类索引、接口索引集合、<clinit>()、<init>()等结构;
    2. 通过对前面例子代码反汇编文件的简单分析,可以发现,一个方法的执行通常会涉及下面几块内存的操作:
      • (1) 虚拟机栈:局部变量表、操作数栈;
      • (2) 堆:通过对象的地址引用去操作;
      • (3) 常量池:引用常量池的一些相关信息;
      • (4)其他如帧数据区、方法区的剩余部分等情况,测试中没有显示出来,这里说明一下;
    展开全文
  • NULL 博文链接:https://josephmok.iteye.com/blog/813774
  • javap命令

    2020-08-07 10:17:37
    javap定义 javap是 Java class文件分解器,可以反编译(即对javac编译的文件进行反编译),也可以查看java编译器生成的字节码。用于分解class文件。 测试类 public class JavapTest { private static final int _P_1...

    在这里插入图片描述

    javap定义
    javap是 Java class文件分解器,可以反编译(即对javac编译的文件进行反编译),也可以查看java编译器生成的字节码。用于分解class文件。
    测试类
    public class JavapTest {

    private static final int _P_1 = 1;
    public static final int _P_2 = 2;
    
    public static void main(String[] args) {
        int m = 0, n = 0;
        for (int i = 0; i < 10; i++) {
            m = m++;
            n = ++n;
        }
        System.out.println("m = " + m);
        System.out.println("n = " + n);
    }
    

    }
    javap命令参数
    C:>javap -help
    用法: javap
    其中, 可能的选项包括:
    -help --help -? 输出此用法消息
    -version 版本信息
    -v -verbose 输出附加信息
    -l 输出行号和本地变量表
    -public 仅显示公共类和成员
    -protected 显示受保护的/公共类和成员
    -package 显示程序包/受保护的/公共类
    和成员 (默认)
    -p -private 显示所有类和成员
    -c 对代码进行反汇编
    -s 输出内部类型签名
    -sysinfo 显示正在处理的类的
    系统信息 (路径, 大小, 日期, MD5 散列)
    -constants 显示静态最终常量
    -classpath 指定查找用户类文件的位置
    -bootclasspath 覆盖引导类文件的位置

    javap -version
    C:>javap -version
    1.7.0_71

    显示java版本

    javap -p
    C:\Users\user\Desktop>javap -p JavapTest.class
    Compiled from “JavapTest.java”
    public class com.method.handler.JavapTest {
    private static final int _P_1;
    public static final int _P_2;
    public com.method.handler.JavapTest();
    public static void main(java.lang.String[]);
    private void say();
    }

    显示类所有可访问修饰符范围》private的成员

    javap -public
    C:\Users\user\Desktop>javap -public JavapTest.class
    Compiled from “JavapTest.java”
    public class com.method.handler.JavapTest {
    public static final int _P_2;
    public com.method.handler.JavapTest();
    public static void main(java.lang.String[]);
    }

    显示类的public成员

    javap -protected
    C:\Users\user\Desktop>javap -protected JavapTest.class
    Compiled from “JavapTest.java”
    public class com.method.handler.JavapTest {
    public static final int _P_2;
    public com.method.handler.JavapTest();
    public static void main(java.lang.String[]);
    }

    显示类所有可访问修饰符范围》protected的成员

    javap -l
    C:\Users\user\Desktop>javap -p -l JavapTest.class
    Compiled from “JavapTest.java”
    public class com.method.handler.JavapTest {
    private static final int _P_1;

    public static final int _P_2;

    public com.method.handler.JavapTest();
    LineNumberTable:
    line 6: 0

    public static void main(java.lang.String[]);
    LineNumberTable:
    line 12: 0
    line 13: 4
    line 14: 12
    line 15: 17
    line 13: 22
    line 17: 28
    line 18: 53
    line 19: 78

    private void say();
    LineNumberTable:
    line 23: 0
    line 24: 8
    }

    输出行号和本地变量表?看的不是很明白

    javap -package
    C:\Users\user\Desktop>javap -package JavapTest.class
    Compiled from “JavapTest.java”
    public class com.method.handler.JavapTest {
    public static final int _P_2;
    public com.method.handler.JavapTest();
    public static void main(java.lang.String[]);
    }

    与javap -public作用类似

    javap -v/-p -v
    C:\Users\user\Desktop>javap -p -v JavapTest.class
    Classfile /C:/Users/frinder_liu/Desktop/JavapTest.class
    Last modified 2016-4-27; size 911 bytes
    MD5 checksum e903be7495f5c462d6459a792e063628
    Compiled from “JavapTest.java”
    public class com.method.handler.JavapTest
    SourceFile: “JavapTest.java”
    minor version: 0
    major version: 51
    flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
    #1 = Methodref #13.#30 // java/lang/Object.""😦)V
    #2 = Fieldref #31.#32 // java/lang/System.out:Ljava/io/PrintStream;
    #3 = Class #33 // java/lang/StringBuilder
    #4 = Methodref #3.#30 // java/lang/StringBuilder.""😦)V
    #5 = String #34 // m =
    #6 = Methodref #3.#35 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilde
    r;
    #7 = Methodref #3.#36 // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
    #8 = Methodref #3.#37 // java/lang/StringBuilder.toString:()Ljava/lang/String;
    #9 = Methodref #38.#39 // java/io/PrintStream.println:(Ljava/lang/String;)V
    #10 = String #40 // n =
    #11 = String #41 // hello world…
    #12 = Class #42 // com/method/handler/JavapTest
    #13 = Class #43 // java/lang/Object
    #14 = Utf8 _P_1
    #15 = Utf8 I
    #16 = Utf8 ConstantValue
    #17 = Integer 1
    #18 = Utf8 _P_2
    #19 = Integer 2
    #20 = Utf8
    #21 = Utf8 ()V
    #22 = Utf8 Code
    #23 = Utf8 LineNumberTable
    #24 = Utf8 main
    #25 = Utf8 ([Ljava/lang/String;)V
    #26 = Utf8 StackMapTable
    #27 = Utf8 say
    #28 = Utf8 SourceFile
    #29 = Utf8 JavapTest.java
    #30 = NameAndType #20:#21 // “”😦)V
    #31 = Class #44 // java/lang/System
    #32 = NameAndType #45:#46 // out:Ljava/io/PrintStream;
    #33 = Utf8 java/lang/StringBuilder
    #34 = Utf8 m =
    #35 = NameAndType #47:#48 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    #36 = NameAndType #47:#49 // append:(I)Ljava/lang/StringBuilder;
    #37 = NameAndType #50:#51 // toString:()Ljava/lang/String;
    #38 = Class #52 // java/io/PrintStream
    #39 = NameAndType #53:#54 // println:(Ljava/lang/String;)V
    #40 = Utf8 n =
    #41 = Utf8 hello world…
    #42 = Utf8 com/method/handler/JavapTest
    #43 = Utf8 java/lang/Object
    #44 = Utf8 java/lang/System
    #45 = Utf8 out
    #46 = Utf8 Ljava/io/PrintStream;
    #47 = Utf8 append
    #48 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
    #49 = Utf8 (I)Ljava/lang/StringBuilder;
    #50 = Utf8 toString
    #51 = Utf8 ()Ljava/lang/String;
    #52 = Utf8 java/io/PrintStream
    #53 = Utf8 println
    #54 = Utf8 (Ljava/lang/String;)V
    {
    private static final int _P_1;
    flags: ACC_PRIVATE, ACC_STATIC, ACC_FINAL
    ConstantValue: int 1

    public static final int _P_2;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    ConstantValue: int 2

    public com.method.handler.JavapTest();
    flags: ACC_PUBLIC
    Code:
    stack=1, locals=1, args_size=1
    0: aload_0
    1: invokespecial #1 // Method java/lang/Object.""😦)V
    4: return
    LineNumberTable:
    line 6: 0

    public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
    stack=3, locals=4, args_size=1
    0: iconst_0
    1: istore_1
    2: iconst_0
    3: istore_2
    4: iconst_0
    5: istore_3
    6: iload_3
    7: bipush 10
    9: if_icmpge 28
    12: iload_1
    13: iinc 1, 1
    16: istore_1
    17: iinc 2, 1
    20: iload_2
    21: istore_2
    22: iinc 3, 1
    25: goto 6
    28: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
    31: new #3 // class java/lang/StringBuilder
    34: dup
    35: invokespecial #4 // Method java/lang/StringBuilder.""😦)V
    38: ldc #5 // String m =
    40: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/St
    ringBuilder;
    43: iload_1
    44: invokevirtual #7 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
    47: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    50: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    53: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
    56: new #3 // class java/lang/StringBuilder
    59: dup
    60: invokespecial #4 // Method java/lang/StringBuilder.""😦)V
    63: ldc #10 // String n =
    65: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/St
    ringBuilder;
    68: iload_2
    69: invokevirtual #7 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
    72: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    75: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    78: return
    LineNumberTable:
    line 12: 0
    line 13: 4
    line 14: 12
    line 15: 17
    line 13: 22
    line 17: 28
    line 18: 53
    line 19: 78
    StackMapTable: number_of_entries = 2
    frame_type = 254 /* append /
    offset_delta = 6
    locals = [ int, int, int ]
    frame_type = 250 /
    chop */
    offset_delta = 21

    private void say();
    flags: ACC_PRIVATE
    Code:
    stack=2, locals=1, args_size=1
    0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
    3: ldc #11 // String hello world…
    5: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    8: return
    LineNumberTable:
    line 23: 0
    line 24: 8
    }

    命令说明是:输出附加信息
    class文件的路径、最后修改时间、文件大小等
    类的全路径、源(java)文件等
    常量池
    常量定义、值
    构造方法
    程序调用及执行逻辑(这个涉及的内容就比较多了)

    总之,javap -v命令是很强大的一个命令!

    javap -c
    C:\Users\user\Desktop>javap -c JavapTest.class
    Compiled from “JavapTest.java”
    public class com.method.handler.JavapTest {
    public static final int _P_2;

    public com.method.handler.JavapTest();
    Code:
    0: aload_0
    1: invokespecial #1 // Method java/lang/Object.""😦)V
    4: return

    public static void main(java.lang.String[]);
    Code:
    0: iconst_0
    1: istore_1
    2: iconst_0
    3: istore_2
    4: iconst_0
    5: istore_3
    6: iload_3
    7: bipush 10
    9: if_icmpge 28
    12: iload_1
    13: iinc 1, 1
    16: istore_1
    17: iinc 2, 1
    20: iload_2
    21: istore_2
    22: iinc 3, 1
    25: goto 6
    28: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
    31: new #3 // class java/lang/StringBuilder
    34: dup
    35: invokespecial #4 // Method java/lang/StringBuilder.""😦)V
    38: ldc #5 // String m =
    40: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/Stri
    ngBuilder;
    43: iload_1
    44: invokevirtual #7 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
    47: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    50: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    53: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
    56: new #3 // class java/lang/StringBuilder
    59: dup
    60: invokespecial #4 // Method java/lang/StringBuilder.""😦)V
    63: ldc #10 // String n =
    65: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/Stri
    ngBuilder;
    68: iload_2
    69: invokevirtual #7 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
    72: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    75: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    78: return
    }

    其实,javap -c 输出内部javap -v中已经有了,我们详细介绍下javap -c命令的输出内容
    0: iconst_0 前面0:表示执行的顺序,iconst_0把值 0 放入栈顶,_0中的0代表压栈的值,如:iconst_5,即把5压入栈顶
    1: istore_1 将栈顶的值放入变量1 中,_1代表变量的序列,本例中为:m,如:istore_2即为变量n赋值
    6: iload_3 将变量3 即 i 的的值放入栈顶,与iconst不同的是,iload操作的值是已经定义好存在的值,iconst是定义时的压栈操作
    13: iinc 1, 1 将变量1 的值加1
    文章开头的demo中最终的结果是什么呢?

    m = 0
    n = 10

    为什么呢?
    我们来关注下这几行:
    12: iload_1 – 将变量1 值放入栈项
    13: iinc 1, 1 – 将变量1 增加1 变为2,栈顶值仍然是1。其中第一个1 表示变量,第二个1 表示增量
    16: istore_1 – 将栈顶值赋值给变量1,变量1 仍然为1
    17: iinc 2, 1 – 将变量2 增加1 变为2,栈顶值仍然是1。其中第一个2 表示变量,第二个1 表示增量
    20: iload_2 – 将变量2 值放入栈顶
    21: istore_2 – 将栈顶值赋值给变量2,变量2 值为2

    记住一个点:
    int m = 0, n = 0;
    m = m++; – 会先将m值(即0)赋值给m后再++
    n = ++n; – n先++后再把值赋值给n
    此时,m = 0, n = 1;
    这个地方有点绕,需要多看几次,理顺逻辑与关系!

    这里可以参考下http://blog.csdn.net/junsure2012/article/details/7099222,讲的很详细也易懂!

    javap -s/-p -s
    C:\Users\user\Desktop>javap -p -s JavapTest.class
    Compiled from “JavapTest.java”
    public class com.method.handler.JavapTest {
    private static final int _P_1;
    Signature: I
    public static final int _P_2;
    Signature: I
    public com.method.handler.JavapTest();
    Signature: ()V

    public static void main(java.lang.String[]);
    Signature: ([Ljava/lang/String;)V

    private void say();
    Signature: ()V
    }

    输出内部类型签名

    javap -sysinfo/-p -sysinfo
    C:\Users\user\Desktop>javap -sysinfo JavapTest.class
    Classfile /C:/Users/user/Desktop/JavapTest.class
    Last modified 2016-4-27; size 911 bytes
    MD5 checksum 3f6dfcf7121785760b234224c5d135fd
    Compiled from “JavapTest.java”
    public class com.method.handler.JavapTest {
    public static final int _P_2;
    public com.method.handler.JavapTest();
    public static void main(java.lang.String[]);
    }

    显示正在处理的类的
    系统信息 (路径, 大小, 日期, MD5 散列)

    javap -constants/-p -constants
    C:\Users\user\Desktop>javap -constants JavapTest.class
    Compiled from “JavapTest.java”
    public class com.method.handler.JavapTest {
    public static final int _P_2 = 2;
    public com.method.handler.JavapTest();
    public static void main(java.lang.String[]);
    }

    显示静态最终常量

    javap -classpath/-bootclasspath

    展开全文
  • leetcode中国-javaP7:JavaP7

    2021-06-29 19:17:50
    javaP7 Hello ,大家好,我是一个JAVA后端研发工程师,之前在国企IT工作了7年,去年十月和女朋友规划了下,决定来互联网看看机会。从十月开始到今年三月,开启了812(每晚8点到12点)学习模式。 今年三月开始找新...
  • sbt-javap 以下如上。 概述 sbt-javap是一个SBT插件,可以直接从SBT调用javap 。 Java提供了javap工具来反汇编和检查Java字节码。 这使作者可以查看其代码如何在较低级别上运行,了解如何对高级Scala概念进行编码...
  • 1. javap相关 javap是官方提供的,用于反编译一个或多个.class文件的java工具,使用javap命令,我们可以查看类的具体信息,有助于我们分析代码的运行状态,更好的理解jvm工作原理。 javap官方文档 2. javap使用格式 ...

    1. javap相关

    javap是官方提供的,用于反编译一个或多个.class文件的java工具,使用javap命令,我们可以查看类的具体信息,有助于我们分析代码的运行状态,更好的理解jvm工作原理。

    javap官方文档

    2. javap使用格式

    javap <options> <classes>
    

    3. option集

      -help  --help  -?        输出此用法消息
      -version                 版本信息
      -v  -verbose             输出附加信息
      -l                       输出行号和本地变量表
      -public                  仅显示公共类和成员
      -protected               显示受保护的/公共类和成员
      -package                 显示程序包/受保护的/公共类
                               和成员 (默认)
      -p  -private             显示所有类和成员
      -c                       对代码进行反汇编
      -s                       输出内部类型签名
      -sysinfo                 显示正在处理的类的
                               系统信息 (路径, 大小, 日期, MD5 散列)
      -constants               显示最终常量
      -classpath <path>        指定查找用户类文件的位置
      -cp <path>               指定查找用户类文件的位置
      -bootclasspath <path>    覆盖引导类文件的位置
    

    4. javap命令展示

    4.1. -version查看版本信息

    javap -version
    1.8.0_211
    

    4.2. -v -verbose查看附加信息

    javap -v -verbose Main.class
    Classfile /D:/project/idea/doit/out/production/doit/cn/yzstu/jvm/Main.class
      Last modified 2021-1-30; size 673 bytes
      MD5 checksum 63f7245b740da5d47dae0b4216057254
      Compiled from "Main.java"
    public class cn.yzstu.jvm.Main
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #10.#28        // java/lang/Object."<init>":()V
       #2 = Class              #29            // java/lang/Thread
       #3 = Methodref          #2.#28         // java/lang/Thread."<init>":()V
       #4 = Class              #30            // cn/yzstu/jvm/Math
       #5 = Methodref          #4.#28         // cn/yzstu/jvm/Math."<init>":()V
       #6 = Methodref          #4.#31         // cn/yzstu/jvm/Math.compute:()I
       #7 = Fieldref           #32.#33        // java/lang/System.out:Ljava/io/PrintStream;
       #8 = Methodref          #34.#35        // java/io/PrintStream.println:(I)V
       #9 = Class              #36            // cn/yzstu/jvm/Main
      #10 = Class              #37            // java/lang/Object
      #11 = Utf8               <init>
      #12 = Utf8               ()V
      #13 = Utf8               Code
      #14 = Utf8               LineNumberTable
      #15 = Utf8               LocalVariableTable
      #16 = Utf8               this
      #17 = Utf8               Lcn/yzstu/jvm/Main;
      #18 = Utf8               main
      #19 = Utf8               ([Ljava/lang/String;)V
      #20 = Utf8               args
      #21 = Utf8               [Ljava/lang/String;
      #22 = Utf8               math
      #23 = Utf8               Lcn/yzstu/jvm/Math;
      #24 = Utf8               compute
      #25 = Utf8               I
      #26 = Utf8               SourceFile
      #27 = Utf8               Main.java
      #28 = NameAndType        #11:#12        // "<init>":()V
      #29 = Utf8               java/lang/Thread
      #30 = Utf8               cn/yzstu/jvm/Math
      #31 = NameAndType        #24:#38        // compute:()I
      #32 = Class              #39            // java/lang/System
      #33 = NameAndType        #40:#41        // out:Ljava/io/PrintStream;
      #34 = Class              #42            // java/io/PrintStream
      #35 = NameAndType        #43:#44        // println:(I)V
      #36 = Utf8               cn/yzstu/jvm/Main
      #37 = Utf8               java/lang/Object
      #38 = Utf8               ()I
      #39 = Utf8               java/lang/System
      #40 = Utf8               out
      #41 = Utf8               Ljava/io/PrintStream;
      #42 = Utf8               java/io/PrintStream
      #43 = Utf8               println
      #44 = Utf8               (I)V
    {
      public cn.yzstu.jvm.Main();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 6: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   Lcn/yzstu/jvm/Main;
    
      public static void main(java.lang.String[]);
        descriptor: ([Ljava/lang/String;)V
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=3, args_size=1
             0: new           #2                  // class java/lang/Thread
             3: dup
             4: invokespecial #3                  // Method java/lang/Thread."<init>":()V
             7: pop
             8: new           #4                  // class cn/yzstu/jvm/Math
            11: dup
            12: invokespecial #5                  // Method cn/yzstu/jvm/Math."<init>":()V
            15: astore_1
            16: aload_1
            17: invokevirtual #6                  // Method cn/yzstu/jvm/Math.compute:()I
            20: istore_2
            21: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
            24: iload_2
            25: invokevirtual #8                  // Method java/io/PrintStream.println:(I)V
            28: return
          LineNumberTable:
            line 8: 0
            line 9: 8
            line 10: 16
            line 11: 21
            line 12: 28
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      29     0  args   [Ljava/lang/String;
               16      13     1  math   Lcn/yzstu/jvm/Math;
               21       8     2 compute   I
    }
    SourceFile: "Main.java"
    

    这一部分信息,建议大家配合我的另一篇文章jvm栈工作原理,里面有分析这些信息的工具

    4.3. -l

    javap -l Main.class
    Compiled from "Main.java"
    public class cn.yzstu.jvm.Main {
      public cn.yzstu.jvm.Main();
        LineNumberTable:
          line 6: 0
        LocalVariableTable:
          Start  Length  Slot  Name   Signature
              0       5     0  this   Lcn/yzstu/jvm/Main;
    
      public static void main(java.lang.String[]);
        LineNumberTable:
          line 8: 0
          line 9: 8
          line 10: 16
          line 11: 21
          line 12: 28
        LocalVariableTable:
          Start  Length  Slot  Name   Signature
              0      29     0  args   [Ljava/lang/String;
             16      13     1  math   Lcn/yzstu/jvm/Math;
             21       8     2 compute   I
    }
    

    4.4. 其他

    剩下的懒得去展示了,自己去执行命令看吧(狗头)

    5. javap实战示例

    jvm栈工作原理中其实有些许体现,但是有些地方没讲清楚,这里说一下我在使用javap命令时的思路

    5.1. 反编译

    首先我们拿到的是.class文件,里面都是字节码,难以阅读,所以首先需要反编译.class字节码,获取指令码

    javap -c Main.class > Main.txt
    

    上面的命令可以将我们的Main.class字节码文件反汇编成指令码,并且保存到同路径下的Main.txt文件中

    Compiled from "Main.java"
    public class cn.yzstu.jvm.Main {
      public cn.yzstu.jvm.Main();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
    
      public static void main(java.lang.String[]);
        Code:
           0: new           #2                  // class java/lang/Thread
           3: dup
           4: invokespecial #3                  // Method java/lang/Thread."<init>":()V
           7: pop
           8: new           #4                  // class cn/yzstu/jvm/Math
          11: dup
          12: invokespecial #5                  // Method cn/yzstu/jvm/Math."<init>":()V
          15: astore_1
          16: aload_1
          17: invokevirtual #6                  // Method cn/yzstu/jvm/Math.compute:()I
          20: istore_2
          21: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
          24: iload_2
          25: invokevirtual #8                  // Method java/io/PrintStream.println:(I)V
          28: return
    }
    

    看不懂指令码的朋友可以扫描文章最下方我的公众号二维码,关注后回复“jvm指令手册”获取文档

    5.2. 查看附加信息

    有些指令码后面带有类似“#5”之类的参数,这些参数代表的意义可以在附加信息中查看,执行一下命令

    javap -v Main.class
    

    在执行结果中的常量池中可以看到其对应的信息

    Constant pool:
       #1 = Methodref          #10.#28        // java/lang/Object."<init>":()V
       #2 = Class              #29            // java/lang/Thread
       #3 = Methodref          #2.#28         // java/lang/Thread."<init>":()V
       #4 = Class              #30            // cn/yzstu/jvm/Math
       #5 = Methodref          #4.#28         // cn/yzstu/jvm/Math."<init>":()V
       #6 = Methodref          #4.#31         // cn/yzstu/jvm/Math.compute:()I
       #7 = Fieldref           #32.#33        // java/lang/System.out:Ljava/io/PrintStream;
       #8 = Methodref          #34.#35        // java/io/PrintStream.println:(I)V
       #9 = Class              #36            // cn/yzstu/jvm/Main
      #10 = Class              #37            // java/lang/Object
      #11 = Utf8               <init>
      #12 = Utf8               ()V
      #13 = Utf8               Code
      #14 = Utf8               LineNumberTable
      #15 = Utf8               LocalVariableTable
      #16 = Utf8               this
      #17 = Utf8               Lcn/yzstu/jvm/Main;
      #18 = Utf8               main
      #19 = Utf8               ([Ljava/lang/String;)V
      #20 = Utf8               args
      #21 = Utf8               [Ljava/lang/String;
      #22 = Utf8               math
      #23 = Utf8               Lcn/yzstu/jvm/Math;
      #24 = Utf8               compute
      #25 = Utf8               I
      #26 = Utf8               SourceFile
      #27 = Utf8               Main.java
      #28 = NameAndType        #11:#12        // "<init>":()V
      #29 = Utf8               java/lang/Thread
      #30 = Utf8               cn/yzstu/jvm/Math
      #31 = NameAndType        #24:#38        // compute:()I
      #32 = Class              #39            // java/lang/System
      #33 = NameAndType        #40:#41        // out:Ljava/io/PrintStream;
      #34 = Class              #42            // java/io/PrintStream
      #35 = NameAndType        #43:#44        // println:(I)V
      #36 = Utf8               cn/yzstu/jvm/Main
      #37 = Utf8               java/lang/Object
      #38 = Utf8               ()I
      #39 = Utf8               java/lang/System
      #40 = Utf8               out
      #41 = Utf8               Ljava/io/PrintStream;
      #42 = Utf8               java/io/PrintStream
      #43 = Utf8               println
      #44 = Utf8               (I)V
    

    这就是阅读指令码的简单实战

    6. 总结

    javap是一个强大工具类,熟练使用后能够帮助你更好的理解java运行机制。

    我是Baldwin,一个25岁的程序员,致力于让学习变得更有趣!
    现在关注作者即可领取海量学习资料与简历模板
    在这里插入图片描述

    往期好文:

    用Python每天给女神发一句手机短信情话

    MySQL优化之explain

    Spring源码分析-MVC初始化

    春风得意马蹄疾,一文看尽(JVM)虚拟机

    造轮子的艺术

    源码阅读技巧

    Java注解详解

    教你自建SpringBoot服务器

    更多文章请点击

    展开全文
  • NULL 博文链接:https://bolinyang.iteye.com/blog/1830472
  • idea配置javap命令

    2021-09-03 13:26:05
    文章目录idea配置javap命令1. 通过idea配置javap -c命令来配置下javap命令1.1 选择File->Settings->Tools->External Tools1.2 点击+号1.3 按如下配置:2 在idea上使用javap -c命令2.1 在当前类上执行javap ...
  • javac 和 javap工具详解

    2020-02-16 20:16:47
    由于javac和javap是两个相反的过程,所以放在一起做分析。 关于javac和javap如果想要做详细的了解,还是需要看Oracle官网的介绍。访问入口如下: javac. javap. 本文内容均为自己阅读文档后自己总结的,如有错误,...
  • javap 反汇编

    2021-08-03 11:31:12
    文章目录1、把一个java类反汇编1.1、写一个类Hello.java1.2、javac 编译1.3、javap 反汇编2、分析汇编代码 1、把一个java类反汇编 1.1、写一个类Hello.java Hello.java public class Hello { private Integer num1 ...
  • 通过javap命令分析java汇编指令一、javap命令简述二、javap测试及内容详解三、总结 一、javap命令简述 javap是jdk自带的反解析工具。它的作用就是根据class字节码文件,反解析出当前类对应的code区(汇编指令)、...
  • )是不是一个原子操作,后来看了别人的解释才发现可以用javap来进项查看: 那么, 一、首先我们得了解什么是javap,它可以用来干啥子? 大多数Java程序员知道他们的程序不是编译成本机代码的。实际上,程序被编译...
  • javap 的用法

    2021-08-06 18:02:40
    在命令行中直接输入javap 或 java -help ,就可以看到javap 的 options有如下选项: E:\jvmp2\chapter01\java1>javap 用法: javap <options> <classes> 其中, 可能的选项包括: -help --help -?...
  • 015-JVM-使用javap查看class文件内容

    万次阅读 2020-12-20 15:08:09
    上一篇:014-JVM-查看class文按键的工具...处理使用上面的工具还可以使用javap查看class文件的格式 1. 使用javap -v 查看Helloworld.class文件 Microsoft Windows [版本 10.0.19041.685] (c) 2020 Microsoft Corporatio
  • 这里借助javap看看其他的情况,javap -verbose TestJVM Classfile /Users/zengzhiqin/Desktop/daima/leetcode/out/production/leetcode/TestJVM.class Last modified 2020-9-20; size 731 bytes MD5 ...
  • javap查看类文件

    2020-06-02 20:09:23
    public class Hello { public static void main(String[] args) { ...javap Hello.class Compiled from "Hello.java" public class com.ghgcn.jvm.chapter01.Hello { public com.ghgcn.jvm.chapter01.Hel..
  • 有时候开发想查看某个类的字节码指令,可以通过IDEA工具集成javap命令实现。 打开preference->Tools->External tools->点击左下角加号新增一个工具 弹出快捷键加入框,键入以下内容,其他都是默认 ...
  • 阿里p6、p7 java
  • javap 命令详解

    2019-09-18 02:17:04
    javap是jdk自带的一个工具,可以反编译,也可以查看java编译器生成的字节码,是分析代码的一个好工具。 javap - Java class文件分解器 分解class文件 摘要: javap [ opt...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,275
精华内容 11,710
关键字:

javap

java 订阅