网站首页 > java教程 正文
class字节码
class文件(二进制)和字节码(十六进制)的关系
- class文件是经过编译器编译后的文件(如javac),一个class文件代表一个类或者接口;class文件主要存储的是字节码,字节码是访问jvm的重要指令,在后面的章节中会介绍字节码的相关信息。jvm规范定义了class文件结构格式,每种jvm实现必须满足规范定义,这样jvm实例才能加载class文件,运行字节码内容。但jvm的实现可以在jvm规范的约束下对具体实现做出修改和优化(如自定义属性信息,jvm会忽略不认识的属性表)。class文件的内容(.class文件本身是2进制)一般是16进制的数。 JVM加载的Class文件不一定来自磁盘,还可以来自网络数据,甚至在运行时直接编译代码字符串生成。 ---------节选《深入了解虚拟机》
- 机器码我理解是CPU的指令集。字节码是由opcode(操作码)和操作数组成的。class文件并不叫字节码,class文件是由字节码组成的。字节码你可以理解为是JVM的指令。JVM是一个运行在CPU上的程序,JVM本身是由一条条机器码组成的,它的功能是读取一条条字节码,并在CPU上执行。
- 也就是说是将二进制的文件加载JVM时,JVM将使用十六进制的方式读取class文件中的字节码(编译期间就确定好了)
.java和.class的区别
- java文件是源文件,通过javac命令编译后生成.class文件;.class文件是字节码结文件,即.java文件编译后的代码。
- class文件全名称为Java class文件,主要在平台无关性和网络移动性方面使Java更适合网络。
- 通俗来说java文件就是这样一个未经编译的源程序,一般是给程序员看的。class文件就是被编译器编译过的java文件,通常是给计算机看的。
- 也就是说.java是我们开发语言.class生成的16进制字节码是方便机器看的因为java源文件存在太多换行导致内存占用过多(机器不会识别空格)
- jvm规范和Java规范是不同的不能拿java的思维去套用jvm
示例
public class MyTest1 {
private int a = 1;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
执行
javac MyTest1.java
//打印公有信息
javap -verbose MyTest1.class
//将私有的方法信息也打印出来
javap -verbose -p MyTest1.class
得到对应字节码
Last modified 2020-9-13; size 375 bytes
MD5 checksum 8ba81fc79a80d987e02b14067a155703
Compiled from "MyTest1.java"
public class com.example.demo.com.jvm.bytecode.MyTest1
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#17 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#18 //com/example/demo/com/jvm/bytecode/MyTest1.a:I
#3 = Class #19 // com/example/demo/com/jvm/bytecode/MyTest1
#4 = Class #20 // java/lang/Object
#5 = Utf8 a
#6 = Utf8 I
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 getA
#12 = Utf8 ()I
#13 = Utf8 setA
#14 = Utf8 (I)V
#15 = Utf8 SourceFile
#16 = Utf8 MyTest1.java
#17 = NameAndType #7:#8 // "<init>":()V
#18 = NameAndType #5:#6 // a:I
#19 = Utf8 com/example/demo/com/jvm/bytecode/MyTest1
#20 = Utf8 java/lang/Object
{
public com.example.demo.com.jvm.bytecode.MyTest1();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>
":()V
4: aload_0
5: iconst_1
6: putfield #2 // Field a:I
9: return
LineNumberTable:
line 3: 0
line 5: 4
public int getA();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #2 // Field a:I
4: ireturn
LineNumberTable:
line 8: 0
public void setA(int);
descriptor: (I)V
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: iload_1
2: putfield #2 // Field a:I
5: return
LineNumberTable:
line 12: 0
line 13: 5
}
SourceFile: "MyTest1.java"
字节码整体结构
class文件只有两种数据类型:无符号数和表
这里面表就类似常量池 是一种数据结构的复合形式
方法区包含如下内容
- 上一篇: 虚拟机字节码操作黑科技工具简介
- 下一篇: 浅谈字节码增强技术系列2-Asm与Cglib
猜你喜欢
- 2025-01-07 Python GUI 编程:tkinter 初学者入门指南——几何布局管理器 Place
- 2025-01-07 偷天换日,用JavaAgent欺骗你的JVM
- 2025-01-07 大数据必学Java基础(二):Java核心机制
- 2025-01-07 求你了,别再说 Java 对象都是在堆内存上分配空间了
- 2025-01-07 Java 虚拟机是什么?——探秘 JVM 的核心机制!
- 2025-01-07 5.2 JVM常见问题及面试题
- 2025-01-07 JVM实战—1.Java代码的运行原理
- 2025-01-07 浅谈字节码增强技术系列2-Asm与Cglib
- 2025-01-07 虚拟机字节码操作黑科技工具简介
- 2025-01-07 什么是 Java 开发工具包 (JDK)?
你 发表评论:
欢迎- 04-24Java Collections 工具类集合框架中常用算法解析
- 04-24桶排序的简单理解
- 04-24Java集合框架底层实现原理大揭秘
- 04-24Java 集合框架全面解析:选对数据结构,提升开发效率
- 04-24c#集合排序
- 04-24Java面试中常被问到的集合类深度解读
- 04-24VBA技术资料MF278:对集合进行排序
- 04-24Spring 最常用的 7 大类注解,史上最强整理
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)