java中的反编译使用的命令


Java开发中偶尔会有使用把编译后的Java文件反编译一下

1.先写一个Java类 Test0

package com.线程.多线程核心技术._2;

public class Test0 {
    synchronized public static void testMethod() {
    }
    public static void main(String[] args) {
    }
}

2.使用命令javac Test0.java,会得到一个文件Test0.class

3.接下反编译。使用命令javap -c -v Test0.class

4.查询反编译的结果

 
Classfile /Users/liyiruo/IdeaProjects/study/src/main/java/com/线程/多线程核心技术/_2/Test0.class
  Last modified 2020-10-9; size 343 bytes
  MD5 checksum c16e6ceada756dd4c2f32daa3747516d
  Compiled from "Test0.java"
public class com.线程.多线程核心技术._2.Test0
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #3.#13         // java/lang/Object."<init>":()V
   #2 = Class              #14            // com/线程/多线程核心技术/_2/Test0
   #3 = Class              #15            // java/lang/Object
   #4 = Utf8               <init>
   #5 = Utf8               ()V
   #6 = Utf8               Code
   #7 = Utf8               LineNumberTable
   #8 = Utf8               testMethod
   #9 = Utf8               main
  #10 = Utf8               ([Ljava/lang/String;)V
  #11 = Utf8               SourceFile
  #12 = Utf8               Test0.java
  #13 = NameAndType        #4:#5          // "<init>":()V
  #14 = Utf8               com/线程/多线程核心技术/_2/Test0
  #15 = Utf8               java/lang/Object
{
  public com.线程.多线程核心技术._2.Test0();
    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 3: 0

  public static synchronized void testMethod();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
    Code:
      stack=0, locals=0, args_size=0
         0: return
      LineNumberTable:
        line 5: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LineNumberTable:
        line 9: 0
}
SourceFile: "Test0.java"

5.解读反编译后的内容

  • synchronized public static void testMethod() { }这个方法的flagsflags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
    指的是访问权限为:public,static,synchronized

6.其他 synchronized 修饰方法和修饰代码块的区别

package com.线程.多线程核心技术._2;

public class Test1 {
    public void myMethod() {
        synchronized (this) {
            int age = 100;
        }
    }

    public static void main(String[] args) {
        Test1 test = new Test1();
        test.myMethod();
    }

}

反编译后结果为:

Classfile /Users/liyiruo/IdeaProjects/study/src/main/java/com/线程/多线程核心技术/_2/Test1.class
  Last modified 2020-10-9; size 495 bytes
  MD5 checksum 9ddb52e82ff02785d9947879aed55dcb
  Compiled from "Test1.java"
public class com.线程.多线程核心技术._2.Test1
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #5.#19         // java/lang/Object."<init>":()V
   #2 = Class              #20            // com/线程/多线程核心技术/_2/Test1
   #3 = Methodref          #2.#19         // com/线程/多线程核心技术/_2/Test1."<init>":()V
   #4 = Methodref          #2.#21         // com/线程/多线程核心技术/_2/Test1.myMethod:()V
   #5 = Class              #22            // java/lang/Object
   #6 = Utf8               <init>
   #7 = Utf8               ()V
   #8 = Utf8               Code
   #9 = Utf8               LineNumberTable
  #10 = Utf8               myMethod
  #11 = Utf8               StackMapTable
  #12 = Class              #20            // com/线程/多线程核心技术/_2/Test1
  #13 = Class              #22            // java/lang/Object
  #14 = Class              #23            // java/lang/Throwable
  #15 = Utf8               main
  #16 = Utf8               ([Ljava/lang/String;)V
  #17 = Utf8               SourceFile
  #18 = Utf8               Test1.java
  #19 = NameAndType        #6:#7          // "<init>":()V
  #20 = Utf8               com/线程/多线程核心技术/_2/Test1
  #21 = NameAndType        #10:#7         // myMethod:()V
  #22 = Utf8               java/lang/Object
  #23 = Utf8               java/lang/Throwable
{
  public com.线程.多线程核心技术._2.Test1();
    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 void myMethod();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=4, args_size=1
         0: aload_0
         1: dup
         2: astore_1
         3: monitorenter
         4: bipush        100
         6: istore_2
         7: aload_1
         8: monitorexit
         9: goto          17
        12: astore_3
        13: aload_1
        14: monitorexit
        15: aload_3
        16: athrow
        17: return
      Exception table:
         from    to  target type
             4     9    12   any
            12    15    12   any
      LineNumberTable:
        line 11: 0
        line 12: 4
        line 13: 7
        line 14: 17
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 12
          locals = [ class com/线程/多线程核心技术/_2/Test1, class java/lang/Object ]
          stack = [ class java/lang/Throwable ]
        frame_type = 250 /* chop */
          offset_delta = 4

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: new           #2                  // class com/线程/多线程核心技术/_2/Test1
         3: dup
         4: invokespecial #3                  // Method "<init>":()V
         7: astore_1
         8: aload_1
         9: invokevirtual #4                  // Method myMethod:()V
        12: return
      LineNumberTable:
        line 17: 0
        line 18: 8
        line 19: 12
}
SourceFile: "Test1.java"

7.重点 字节码中使用了monitorenter和monitorexit

public void myMethod();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=4, args_size=1
         0: aload_0
         1: dup
         2: astore_1
         3: monitorenter
         4: bipush        100
         6: istore_2
         7: aload_1
         8: monitorexit
         9: goto          17
        12: astore_3
        13: aload_1
        14: monitorexit
        15: aload_3
        16: athrow
        17: return

8.总结:

synchronized 修饰方法 方法的flags上有acc_synchronized
synchronized 修饰代码块 字节码中使用了monitorenter 和 monitorexit

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值