package lock;
public class ByteCodeTest {
private volatile String name="view";
public void work(){
name+="hello";
}
}
// class version 56.0 (56)
// access flags 0x21
public class lock/ByteCodeTest {
// compiled from: ByteCodeTest.java
// access flags 0x19
public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup
// access flags 0x42
private volatile Ljava/lang/String; name
// access flags 0x1
public <init>()V
L0
LINENUMBER 3 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
L1
LINENUMBER 4 L1
ALOAD 0
LDC "view"
PUTFIELD lock/ByteCodeTest.name : Ljava/lang/String;
RETURN
L2
LOCALVARIABLE this Llock/ByteCodeTest; L0 L2 0
MAXSTACK = 2
MAXLOCALS = 1
// access flags 0x1
public work()V
L0
LINENUMBER 6 L0
ALOAD 0
DUP
GETFIELD lock/ByteCodeTest.name : Ljava/lang/String;
INVOKEDYNAMIC makeConcatWithConstants(Ljava/lang/String;)Ljava/lang/String; [
// handle kind 0x6 : INVOKESTATIC
java/lang/invoke/StringConcatFactory.makeConcatWithConstants(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
// arguments:
"\u0001hello"
]
PUTFIELD lock/ByteCodeTest.name : Ljava/lang/String;
L1
LINENUMBER 7 L1
RETURN
L2
LOCALVARIABLE this Llock/ByteCodeTest; L0 L2 0
MAXSTACK = 2
MAXLOCALS = 1
}
package core.object_create;
public class ObjectTest {
private String name = "v2";
public void add() {
int i10 = -1;
int i0 = 5;
int i1 = 6;
int i2 = 127;
int i3 = 150;
int sum = i10 + i0 + i1 + i2 + i3;
}
}
public class core/object_create/ObjectTest {
private Ljava/lang/String; name
// access flags 0x1
public <init>()V
L0
LINENUMBER 3 L0
ALOAD 0 //将指定的引用类型本地变量推送至栈顶
INVOKESPECIAL java/lang/Object.<init> ()V //调用超类构造方法,实例初始化方法,私有方法
L1
LINENUMBER 4 L1
ALOAD 0
LDC "v2" //将int, float或String型常量值从常量池中推送至栈顶
PUTFIELD core/object_create/ObjectTest.name : Ljava/lang/String; //为指定的类的实例域赋值
RETURN //从当前方法返回void
L2
LOCALVARIABLE this Lcore/object_create/ObjectTest; L0 L2 0
MAXSTACK = 2 //代表了操作数栈(Operand Stacks)深度的最大值
MAXLOCALS = 1 //代表了局部变量表所需的存储空间
// access flags 0x1
public add()V
L0 //表示一个局部变量
LINENUMBER 6 L0 //标识变量对应行
ICONST_M1 //将int型-1推送至栈顶
ISTORE 1 //将栈顶int型数值存入指定本地变量
L1
LINENUMBER 7 L1
ICONST_5 //将int型5推送至栈顶
ISTORE 2
L2
LINENUMBER 8 L2
BIPUSH 6 //将单字节的常量值(-128~127)推送至栈顶
ISTORE 3
L3
LINENUMBER 9 L3
BIPUSH 127
ISTORE 4
L4
LINENUMBER 10 L4
SIPUSH 150
ISTORE 5
L5
LINENUMBER 11 L5
ILOAD 1 //将指定的int型本地变量推送至栈顶
ILOAD 2
IADD //将栈顶两int型数值相加并将结果压入栈顶
ILOAD 3
IADD
ILOAD 4
IADD
ILOAD 5
IADD
ISTORE 6
L6
LINENUMBER 12 L6
RETURN
L7
LOCALVARIABLE this Lcore/object_create/ObjectTest; L0 L7 0
LOCALVARIABLE i10 I L1 L7 1
LOCALVARIABLE i0 I L2 L7 2
LOCALVARIABLE i1 I L3 L7 3
LOCALVARIABLE i2 I L4 L7 4
LOCALVARIABLE i3 I L5 L7 5
LOCALVARIABLE sum I L6 L7 6
MAXSTACK = 2
MAXLOCALS = 7
}
1
anerinck 2020-04-14 09:52:50 +08:00
我觉得直接看字节码的十六进制比阅读反编译要清楚。。如果是要了解指令的话不如去搜索一下 jvm 的指令集一类的?
|
2
misaka19000 2020-04-14 09:53:04 +08:00
《深入理解 Java 虚拟机》第 6 章
|
3
CRUD 2020-04-14 09:54:15 +08:00
|
4
guxingke 2020-04-14 10:15:11 +08:00
|
5
lqw3030 OP |
6
maokabc 2020-04-14 10:27:21 +08:00 via Android
java 虚拟机规范,或者可以看 jasmin 的语法,感觉比这个更好理解,还能修改了再编译回 class
|
7
choiwanxy 2020-04-14 10:34:45 +08:00
首先你要分得清哪里是什么,比如哪里是常量池,哪里是无参构架函数,哪里是方法对应的字节码。找到你要看的方法,看 jvm 指令,一个个去查是什么意思。
|
8
itning 2020-04-14 12:16:23 +08:00 via Android
|
10
CFM880 2020-04-14 13:09:45 +08:00
|
11
CFM880 2020-04-14 13:23:23 +08:00
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html
这一章介绍了 ClassFile Structure,先整体了解字节码文件结构,结构嵌套结构,后面再到方法区的指令,比较容易一些,直接上指令集,可以按照字节码文件结构规定的字节来分析一下 ClassFile { u4 magic; #u4 4 个字节魔数 u2 minor_version; #2 个字节小版本号 u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; } |