Java字节码是java源文件编译只有的产物,供jvm加载执行的十六进制数据。
在字节码文件中,每2个字符作为一个字节。
jvm字节码描述了java编译以后的产物。主要由以下几部分组成:
1. 魔数,作为class文件的标识
2. 主次版本号
3. 常量池
4. accessFlag 访问标志
5. 类名
6. 父类名
7. 接口数量
8. field数,field表
9. 方法数,方法表
10. attribute数 attribute表
......
以上各数据组合成一个完整的字节码文件,包括了我们在java类中标书的一切信息,
只不过是以字节码形式存在的,主要供机器读取,而不是正常人。
java 创新性的提出字节码的概念,这是java语言可以跨平台的重要存在。
java 和 jvm虚拟机
java语言规范和jvm虚拟机规范是分开的。java语言只不过是jvm规范中一个最重要的分支。
原则上只要是符合规范的字节码文件,jvm都可以执行。jvm并不关心class文件的来源。
以及class文件是由于哪些语言编译的产物。
事实上,jython,jruby groovy 等都是运行在jvm之上的语言。
在以后的文章中会针对一个简单类的字节码进行反编译,来深入进行字节码学习。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class MyClass {
private static int a = 1; public int getA() { return this.a; } public void setA(int a) { this.a = a; }
}
|
对以上源文件生成的字节码进行反编译,得到结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| Last modified Jul 25, 2019; size 524 bytes MD5 checksum e846819608e7bc904c06a8545263fac1 Compiled from "MyClass.java" public class com.example.lib.MyClass minor version: 0 major version: 51 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #4.#21 #2 = Fieldref #3.#22 #3 = Class #23 #4 = Class #24 #5 = Utf8 a #6 = Utf8 I #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 LocalVariableTable #12 = Utf8 this #13 = Utf8 Lcom/example/lib/MyClass; #14 = Utf8 getA #15 = Utf8 ()I #16 = Utf8 setA #17 = Utf8 (I)V #18 = Utf8 <clinit> #19 = Utf8 SourceFile #20 = Utf8 MyClass.java #21 = NameAndType #7:#8 #22 = NameAndType #5:#6 #23 = Utf8 com/example/lib/MyClass #24 = Utf8 java/lang/Object { public com.example.lib.MyClass(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 4: return LineNumberTable: line 3: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/example/lib/MyClass;
public int getA(); descriptor: ()I flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: pop 2: getstatic #2 5: ireturn LineNumberTable: line 8: 0 LocalVariableTable: Start Length Slot Name Signature 0 6 0 this Lcom/example/lib/MyClass;
public void setA(int); descriptor: (I)V flags: ACC_PUBLIC Code: stack=1, locals=2, args_size=2 0: aload_0 1: pop 2: iload_1 3: putstatic #2 6: return LineNumberTable: line 12: 0 line 13: 6 LocalVariableTable: Start Length Slot Name Signature 0 7 0 this Lcom/example/lib/MyClass; 0 7 1 a I
static {}; descriptor: ()V flags: ACC_STATIC Code: stack=1, locals=0, args_size=0 0: iconst_1 1: putstatic #2 4: return LineNumberTable: line 5: 0 } SourceFile: "MyClass.java"
|
我们用工具打开字节码文件,可以看到以下16进制的数据
在后续章节将会对字节码文件进行一个详细的阐述和分析