查看.class文件的各种形式及含义

查看16进制:

public class ByteCode {

    private int m;

    public int inc() {
        return m + 1;
    }

}
javac ByteCode.java
vim ByteCode.class
:%!xxd
00000000: cafe babe 0000 0034 0013 0a00 0400 0f09  .......4........
00000010: 0003 0010 0700 1107 0012 0100 016d 0100  .............m..
00000020: 0149 0100 063c 696e 6974 3e01 0003 2829  .I...<init>...()
00000030: 5601 0004 436f 6465 0100 0f4c 696e 654e  V...Code...LineN
00000040: 756d 6265 7254 6162 6c65 0100 0369 6e63  umberTable...inc
00000050: 0100 0328 2949 0100 0a53 6f75 7263 6546  ...()I...SourceF
00000060: 696c 6501 000d 4279 7465 436f 6465 2e6a  ile...ByteCode.j
00000070: 6176 610c 0007 0008 0c00 0500 0601 001b  ava.............
00000080: 636f 6d2f 6578 616d 706c 652f 6465 6d6f  com/example/demo

各字节含义:按顺序(u1 u2 u4 u8分别代表1 2 4 8字节,其他是表类型)
[图片来源:深入理解java虚拟机 第2版]
在这里插入图片描述
计算得出 更直观展示各字节含义:

javap -verbose ByteCode.class
Classfile xxxx/ByteCode.class
  Last modified 2018-9-30; size 292 bytes
  MD5 checksum 775471577fc46c33efff4361644724aa
  Compiled from "ByteCode.java"
public class com.example.demoms.ByteCode
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #4.#15         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#16         // com/example/demoms/ByteCode.m:I
   #3 = Class              #17            // com/example/demoms/ByteCode
   #4 = Class              #18            // java/lang/Object
   #5 = Utf8               m
   #6 = Utf8               I
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               inc
  #12 = Utf8               ()I
  #13 = Utf8               SourceFile
  #14 = Utf8               ByteCode.java
  #15 = NameAndType        #7:#8          // "<init>":()V
  #16 = NameAndType        #5:#6          // m:I
  #17 = Utf8               com/example/demoms/ByteCode
  #18 = Utf8               java/lang/Object
{
  public com.example.demoms.ByteCode();
    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 9: 0

  public int inc();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: getfield      #2                  // Field m:I
         4: iconst_1
         5: iadd
         6: ireturn
      LineNumberTable:
        line 14: 0
}
SourceFile: "ByteCode.java"

查看字节码指令:(jvm指令)

javap -c ByteCode.class
public class com.example.demoms.ByteCode {
  public com.example.demoms.ByteCode();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public int inc();
    Code:
       0: aload_0
       1: getfield      #2                  // Field m:I
       4: iconst_1
       5: iadd
       6: ireturn
}

查看反汇编指令:

/**
 *JVM参数输出反汇编
 * -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
 */
public class ByteCode {

    private int m;

    public int inc() {
        return m + 1;
    }

    public static void main(String[] args) {

    }

}

反汇编输出的代码有点多…部分如下:

Loaded disassembler from hsdis-amd64.dylib
Decoding compiled method 0x000000010e198610:
Code:
[Disassembling for mach='i386:x86-64']
[Entry Point]
[Constants]
  # {method} {0x00000001070e6480} '<init>' '()V' in 'java/lang/Object'
  #           [sp+0x20]  (sp of caller)
  0x000000010e198760: mov    0x8(%rsi),%r10d
  0x000000010e198764: shl    $0x3,%r10
  0x000000010e198768: cmp    %r10,%rax
  0x000000010e19876b: jne    0x000000010e0d8e60  ;   {runtime_call}
  0x000000010e198771: data32 xchg %ax,%ax
  0x000000010e198774: nopl   0x0(%rax,%rax,1)
  0x000000010e19877c: data32 data32 xchg %ax,%ax
[Verified Entry Point]
  0x000000010e198780: mov    %eax,-0x14000(%rsp)
  0x000000010e198787: push   %rbp
  0x000000010e198788: sub    $0x10,%rsp         ;*synchronization entry
                                                ; - java.lang.Object::<init>@-1 (line 37)

  0x000000010e19878c: mov    0x8(%rsi),%r11d
  0x000000010e198790: movabs $0x0,%r10
  0x000000010e19879a: lea    (%r10,%r11,8),%r10
  0x000000010e19879e: mov    $0x40000000,%r8d
  0x000000010e1987a4: test   %r8d,0x9c(%r10)
  0x000000010e1987ab: je     0x000000010e1987b8  ;*return
                                                ; - java.lang.Object::<init>@0 (line 37)

  0x000000010e1987ad: mov    %rsi,%rbp
  0x000000010e1987b0: data32 xchg %ax,%ax
  0x000000010e1987b3: callq  0x000000010e104960  ; OopMap{rbp=Oop off=88}
                                                ;*return
                                                ; - java.lang.Object::<init>@0 (line 37)
                                                ;   {runtime_call}
  0x000000010e1987b8: add    $0x10,%rsp
  0x000000010e1987bc: pop    %rbp
  0x000000010e1987bd: test   %eax,-0xd7a47c3(%rip)        # 0x00000001009f4000
                                                ;   {poll_return}
  0x000000010e1987c3: retq                      ;*return
                                                ; - java.lang.Object::<init>@0 (line 37)

  0x000000010e1987c4: mov    %rax,%rsi
  0x000000010e1987c7: add    $0x10,%rsp
  0x000000010e1987cb: pop    %rbp
  0x000000010e1987cc: jmpq   0x000000010e104760  ;   {runtime_call}
  0x000000010e1987d1: hlt    
  0x000000010e1987d2: hlt    
  0x000000010e1987d3: hlt    
  0x000000010e1987d4: hlt    
  0x000000010e1987d5: hlt    
  0x000000010e1987d6: hlt    
  0x000000010e1987d7: hlt    
  0x000000010e1987d8: hlt    
  0x000000010e1987d9: hlt    
  0x000000010e1987da: hlt    
  0x000000010e1987db: hlt    
  0x000000010e1987dc: hlt    
  0x000000010e1987dd: hlt    
  0x000000010e1987de: hlt    
  0x000000010e1987df: hlt    
[Exception Handler]
[Stub Code]
  0x000000010e1987e0: jmpq   0x000000010e1017e0  ;   {no_reloc}
[Deopt Handler Code]
  0x000000010e1987e5: callq  0x000000010e1987ea
  0x000000010e1987ea: subq   $0x5,(%rsp)
  0x000000010e1987ef: jmpq   0x000000010e0da500  ;   {runtime_call}
  0x000000010e1987f4: hlt    
  0x000000010e1987f5: hlt    
  0x000000010e1987f6: hlt    
  0x000000010e1987f7: hlt    
Decoding compiled method 0x000000010e1988d0:
Code:
[Entry Point]
[Verified Entry Point]

当然也可以使用一些其他的反编译插件

猜你喜欢

转载自blog.csdn.net/qq_35119422/article/details/82911001
今日推荐