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 lockByteCodeTest { // 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 guxigke 2020-04-14 10:15:11 +08:00 |
![]() | 5 xyooyx 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 a href="/member/CFM880" class="dark">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]; } |