【JAVA】javap——字节码格式查看工具

来源:互联网 发布:网络美工是什么 编辑:程序博客网 时间:2024/06/06 09:14
D:\workspace\luna_sr2_ws00\demo\bin\cn\wxy\demo>javap -verbose Test
╛»╕µ: ╢■╜°╓╞╬─╝■Test░ⁿ║¼cn.wxy.demo.Test
Classfile /D:/workspace/luna_sr2_ws00/demo/bin/cn/wxy/demo/Test.class
  Last modified 2015-4-8; size 772 bytes
  MD5 checksum a3df72a41ad1c729df494f344da8f345
  Compiled from "Test.java"
public class cn.wxy.demo.Test
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Class              #2             // cn/wxy/demo/Test
   #2 = Utf8               cn/wxy/demo/Test
   #3 = Class              #4             // java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          // java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          // "<init>":()V
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcn/wxy/demo/Test;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Utf8               Exceptions
  #17 = Class              #18            // java/io/UnsupportedEncodingExceptio
n
  #18 = Utf8               java/io/UnsupportedEncodingException
  #19 = String             #20            // ╚²┤╬╬╒╩╓
  #20 = Utf8               ╚²┤╬╬╒╩╓
  #21 = String             #22            // UTF-8
  #22 = Utf8               UTF-8
  #23 = Methodref          #24.#26        // java/net/URLEncoder.encode:(Ljava/l
ang/String;Ljava/lang/String;)Ljava/lang/String;
  #24 = Class              #25            // java/net/URLEncoder
  #25 = Utf8               java/net/URLEncoder
  #26 = NameAndType        #27:#28        // encode:(Ljava/lang/String;Ljava/lan
g/String;)Ljava/lang/String;
  #27 = Utf8               encode
  #28 = Utf8               (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Stri
ng;
  #29 = Fieldref           #30.#32        // java/lang/System.out:Ljava/io/Print
Stream;
  #30 = Class              #31            // java/lang/System
  #31 = Utf8               java/lang/System
  #32 = NameAndType        #33:#34        // out:Ljava/io/PrintStream;
  #33 = Utf8               out
  #34 = Utf8               Ljava/io/PrintStream;
  #35 = Methodref          #36.#38        // java/io/PrintStream.println:(Ljava/
lang/String;)V
  #36 = Class              #37            // java/io/PrintStream
  #37 = Utf8               java/io/PrintStream
  #38 = NameAndType        #39:#40        // println:(Ljava/lang/String;)V
  #39 = Utf8               println
  #40 = Utf8               (Ljava/lang/String;)V
  #41 = Utf8               args
  #42 = Utf8               [Ljava/lang/String;
  #43 = Utf8               fileName
  #44 = Utf8               Ljava/lang/String;
  #45 = Utf8               SourceFile
  #46 = Utf8               Test.java
{
  public cn.wxy.demo.Test();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>
":()V
         4: return
      LineNumberTable:
        line 6: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcn/wxy/demo/Test;


  public static void main(java.lang.String[]) throws java.io.UnsupportedEncoding
Exception;
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Exceptions:
      throws java.io.UnsupportedEncodingException
    Code:
      stack=2, locals=2, args_size=1
         0: ldc           #19                 // String ╚²┤╬╬╒╩╓
         2: ldc           #21                 // String UTF-8
         4: invokestatic  #23                 // Method java/net/URLEncoder.enco
de:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
         7: astore_1
         8: getstatic     #29                 // Field java/lang/System.out:Ljav
a/io/PrintStream;
        11: aload_1
        12: invokevirtual #35                 // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
        15: return
      LineNumberTable:
        line 8: 0
        line 9: 8
        line 10: 15
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      16     0  args   [Ljava/lang/String;
            8       8     1 fileName   Ljava/lang/String;
}

SourceFile: "Test.java"

---------------------------------------------------------------------------------------我是分割线

javap字节码对应的源码小样

package cn.wxy.demo;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;public class Test {public static void main(String[] args) throws UnsupportedEncodingException {String fileName = URLEncoder.encode("Èý´ÎÎÕÊÖ", "UTF-8");System.out.println(fileName);}}

---------------------------------------------------------------------------------------我是分割线

java字节码格式简单介绍:

1. 魔数:用于JVM识别,四个字节。魔数的应用场景太多了,例如图片上传的时候,扩展名、MIME(content-type)检查图片类型都可作假,但是魔数就不容易作假了,此处JVM引入魔数也是这样的道理,用于快速识别该文件是否能被JVM接受(即是不是一个字节码文件)。

2. 主版本号和次版本号:各两个字节。Java的版本号是从45开始的,用于标注编译该字节码的JDK版本,引入版本号的目的是“高版本的JDK能够向下兼容低版本号的class文件,但是不能兼容高版本的class文件。这样也是有必要的,在JVM加载字节码的时候就把隐患扼杀在摇篮中,防止意外产生。

3. 常量池:用于存放字面量和符号引用。因为JVM加载class文件的时候是动态链接,即自字段、方法等不经过运行期转换是无法得到真正的内存入口地址,因此当虚拟机运行的时候就需要从常量池获得符号链接等。

4. 类索引、父类索引、接口索引集合:这三项用来确定一个类的继承关系,均是全限定类名。

5. 字段表:用于描述类或接口中声明的变量,包括实例变量和类变量,但是不包括在方法中声明的变量(这部分在栈帧结构中),只是对属性的描述(作用域啊、类型、名称啊等等),不包含具体的名称、类型,因为需要在运行时引用常量池。

6. 方法表:和字段表一样,只有方法的描述,其具体的代码存在于属性表中的code字段;

7. 属性表:class文件、字段表、方法表都有自己的code属性,code属性用于描述某些场景专有的信息。Java程序方法体中的代码经过javac编译后,最终变成字节码指令存储在code属性中,code属性中有字段描述该方法被调用执行的时候形成栈帧需要分配多大的空间(max_stack)。

属性表code属性之后是exceptioin属性,之后还有很多其他的属性,在此不一一讨论。


javap工具在JDK/bin安装目录下就有,结合《深入Java虚拟机》(周志明著)一书,可以深入理解JVM原理。(本文仅作备份,以助于自己后续技术提高防遗)

0 0
原创粉丝点击