有时候需要使用到java的字节码,参考了相关的博客,如这个:
将java文件编译成字节码文件,再到反编译,字节码指令剖析
使用这个命令就可以生成类对应的字节码了:
如对VolatileDemo.java
javap -c -verbose VolatileDemo.class
如何在AndroidStudio/Idea中添加工具呢,
File->Settings->Tools->External Tools 扩展工具栏
新建一个
截图
其中:program:
$JDKPath$/bin/javap
Agruments:
-classpath $OutputPath$ -c -verbose $FileClass$
Working directory:
$ProjectFileDir$
保存。
然后编译一下,保证我们的java代码已经生成了class文件,
右键对着VolatileDemo.java文件,
package com.by5388.demo.asdpap.thread;
/**
* @author admin on 2021/5/7.
*/
public class VolatileDemo {
static volatile int rate = 0;
private static final int THREAD_COUNT = 20;
private static void increase() {
synchronized (VolatileDemo.class) {
rate++;
}
}
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 10000; j++) {
increase();
}
}
}).start();
}
System.out.println("当前线程数量_ = " + Thread.activeCount());
while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println("当前线程数量 = " + Thread.activeCount());
System.out.println("rate = " + rate);
}
}
选择External ->“反编译->字节码”,即可看到终端中有如下
Classfile /D:/code/androidDemo/AndroidConcurrency/thread/build/classes/java/main/com/by5388/demo/asdpap/thread/VolatileDemo.class
Last modified 2021-5-7; size 1613 bytes
MD5 checksum cbf71816c44c3b9ab6c51fb2b23cff51
Compiled from "VolatileDemo.java"
public class com.by5388.demo.asdpap.thread.VolatileDemo
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#49 // com/by5388/demo/asdpap/thread/VolatileDemo.increase:()V
#2 = Methodref #22.#50 // java/lang/Object."<init>":()V
#3 = Class #51 // com/by5388/demo/asdpap/thread/VolatileDemo
#4 = Fieldref #3.#52 // com/by5388/demo/asdpap/thread/VolatileDemo.rate:I
#5 = Class #53 // java/lang/Thread
#6 = Class #54 // com/by5388/demo/asdpap/thread/VolatileDemo$1
#7 = Methodref #6.#50 // com/by5388/demo/asdpap/thread/VolatileDemo$1."<init>":()V
#8 = Methodref #5.#55 // java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
#9 = Methodref #5.#56 // java/lang/Thread.start:()V
#10 = Fieldref #57.#58 // java/lang/System.out:Ljava/io/PrintStream;
#11 = Class #59 // java/lang/StringBuilder
#12 = Methodref #11.#50 // java/lang/StringBuilder."<init>":()V
#13 = String #60 // 褰撳墠绾跨▼鏁伴噺_ =
#14 = Methodref #11.#61 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#15 = Methodref #5.#62 // java/lang/Thread.activeCount:()I
#16 = Methodref #11.#63 // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
#17 = Methodref #11.#64 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#18 = Methodref #65.#66 // java/io/PrintStream.println:(Ljava/lang/String;)V
#19 = Methodref #5.#67 // java/lang/Thread.yield:()V
#20 = String #68 // 褰撳墠绾跨▼鏁伴噺 =
#21 = String #69 // rate =
#22 = Class #70 // java/lang/Object
#23 = Utf8 InnerClasses
#24 = Utf8 rate
#25 = Utf8 I
#26 = Utf8 THREAD_COUNT
#27 = Utf8 ConstantValue
#28 = Integer 20
#29 = Utf8 <init>
#30 = Utf8 ()V
#31 = Utf8 Code
#32 = Utf8 LineNumberTable
#33 = Utf8 LocalVariableTable
#34 = Utf8 this
#35 = Utf8 Lcom/by5388/demo/asdpap/thread/VolatileDemo;
#36 = Utf8 increase
#37 = Utf8 StackMapTable
#38 = Class #70 // java/lang/Object
#39 = Class #71 // java/lang/Throwable
#40 = Utf8 main
#41 = Utf8 ([Ljava/lang/String;)V
#42 = Utf8 i
#43 = Utf8 args
#44 = Utf8 [Ljava/lang/String;
#45 = Utf8 access$000
#46 = Utf8 <clinit>
#47 = Utf8 SourceFile
#48 = Utf8 VolatileDemo.java
#49 = NameAndType #36:#30 // increase:()V
#50 = NameAndType #29:#30 // "<init>":()V
#51 = Utf8 com/by5388/demo/asdpap/thread/VolatileDemo
#52 = NameAndType #24:#25 // rate:I
#53 = Utf8 java/lang/Thread
#54 = Utf8 com/by5388/demo/asdpap/thread/VolatileDemo$1
#55 = NameAndType #29:#72 // "<init>":(Ljava/lang/Runnable;)V
#56 = NameAndType #73:#30 // start:()V
#57 = Class #74 // java/lang/System
#58 = NameAndType #75:#76 // out:Ljava/io/PrintStream;
#59 = Utf8 java/lang/StringBuilder
#60 = Utf8 褰撳墠绾跨▼鏁伴噺_ =
#61 = NameAndType #77:#78 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#62 = NameAndType #79:#80 // activeCount:()I
#63 = NameAndType #77:#81 // append:(I)Ljava/lang/StringBuilder;
#64 = NameAndType #82:#83 // toString:()Ljava/lang/String;
#65 = Class #84 // java/io/PrintStream
#66 = NameAndType #85:#86 // println:(Ljava/lang/String;)V
#67 = NameAndType #87:#30 // yield:()V
#68 = Utf8 褰撳墠绾跨▼鏁伴噺 =
#69 = Utf8 rate =
#70 = Utf8 java/lang/Object
#71 = Utf8 java/lang/Throwable
#72 = Utf8 (Ljava/lang/Runnable;)V
#73 = Utf8 start
#74 = Utf8 java/lang/System
#75 = Utf8 out
#76 = Utf8 Ljava/io/PrintStream;
#77 = Utf8 append
#78 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#79 = Utf8 activeCount
#80 = Utf8 ()I
#81 = Utf8 (I)Ljava/lang/StringBuilder;
#82 = Utf8 toString
#83 = Utf8 ()Ljava/lang/String;
#84 = Utf8 java/io/PrintStream
#85 = Utf8 println
#86 = Utf8 (Ljava/lang/String;)V
#87 = Utf8 yield
{
static volatile int rate;
descriptor: I
flags: ACC_STATIC, ACC_VOLATILE
public com.by5388.demo.asdpap.thread.VolatileDemo();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #2 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/by5388/demo/asdpap/thread/VolatileDemo;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=4, locals=2, args_size=1
0: iconst_0
1: istore_1
2: iload_1
3: bipush 20
5: if_icmpge 31
8: new #5 // class java/lang/Thread
11: dup
12: new #6 // class com/by5388/demo/asdpap/thread/VolatileDemo$1
15: dup
16: invokespecial #7 // Method com/by5388/demo/asdpap/thread/VolatileDemo$1."<init>":()V
19: invokespecial #8 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
22: invokevirtual #9 // Method java/lang/Thread.start:()V
25: iinc 1, 1
28: goto 2
31: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream;
34: new #11 // class java/lang/StringBuilder
37: dup
38: invokespecial #12 // Method java/lang/StringBuilder."<init>":()V
41: ldc #13 // String 褰撳墠绾跨▼鏁伴噺_ =
43: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
46: invokestatic #15 // Method java/lang/Thread.activeCount:()I
49: invokevirtual #16 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
52: invokevirtual #17 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
55: invokevirtual #18 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
58: invokestatic #15 // Method java/lang/Thread.activeCount:()I
61: iconst_1
62: if_icmple 71
65: invokestatic #19 // Method java/lang/Thread.yield:()V
68: goto 58
71: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream;
74: new #11 // class java/lang/StringBuilder
77: dup
78: invokespecial #12 // Method java/lang/StringBuilder."<init>":()V
81: ldc #20 // String 褰撳墠绾跨▼鏁伴噺 =
83: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
86: invokestatic #15 // Method java/lang/Thread.activeCount:()I
89: invokevirtual #16 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
92: invokevirtual #17 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
95: invokevirtual #18 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
98: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream;
101: new #11 // class java/lang/StringBuilder
104: dup
105: invokespecial #12 // Method java/lang/StringBuilder."<init>":()V
108: ldc #21 // String rate =
110: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
113: getstatic #4 // Field rate:I
116: invokevirtual #16 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
119: invokevirtual #17 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
122: invokevirtual #18 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
125: return
LineNumberTable:
line 18: 0
line 19: 8
line 26: 22
line 18: 25
line 28: 31
line 30: 58
line 31: 65
line 35: 71
line 36: 98
line 37: 125
LocalVariableTable:
Start Length Slot Name Signature
2 29 1 i I
0 126 0 args [Ljava/lang/String;
StackMapTable: number_of_entries = 4
frame_type = 252 /* append */
offset_delta = 2
locals = [ int ]
frame_type = 250 /* chop */
offset_delta = 28
frame_type = 26 /* same */
frame_type = 12 /* same */
static void access$000();
descriptor: ()V
flags: ACC_STATIC, ACC_SYNTHETIC
Code:
stack=0, locals=0, args_size=0
0: invokestatic #1 // Method increase:()V
3: return
LineNumberTable:
line 6: 0
static {};
descriptor: ()V
flags: ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: iconst_0
1: putstatic #4 // Field rate:I
4: return
LineNumberTable:
line 8: 0
}
SourceFile: "VolatileDemo.java"
InnerClasses:
static #6; //class com/by5388/demo/asdpap/thread/VolatileDemo$1
Process finished with exit code 0
就是相关的字节码了。
网友评论