读懂Java字节码文件(1)

文章详细解析了Java程序中main方法的字节码执行过程,涉及操作数栈、局部变量表、虚拟机栈的工作原理,并以MyBatis为例,强调自我总结学习的重要性。同时提到了相关学习资源如MyBatis源码分析文档和面试解析资料。
摘要由CSDN通过智能技术生成

同理可得:

#2 代表一个PrintStream对象,即System.out

#3 代表一个字符串,即"Hello World"

#4 代表PrintStream类定义的带一个String参数的方法println

#5 代表HelloWorld类

#6 代表Object类

3.代码信息


{

public com.qfc.test.thread.HelloWorld();

descriptor: ()V

flags: ACC_PUBLIC

Code:

stack=1, locals=1, args_size=1

0: aload_0

1: invokespecial #1 // Method java/lang/Object.“”😦)V

4: return

LineNumberTable:

line 3: 0

LocalVariableTable:

Start Length Slot Name Signature

0 5 0 this Lcom/qfc/test/thread/HelloWorld;

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=1, args_size=1

0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

3: ldc #3 // String Hello World

5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

8: return

LineNumberTable:

line 5: 0

line 6: 8

LocalVariableTable:

Start Length Slot Name Signature

0 9 0 args [Ljava/lang/String;

}

SourceFile: “HelloWorld.java”

代码中主要包含字段,构造器(代码块),方法等信息

我们以main方法为例

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V 描述方法是带一个String数组参数的方法,[代表数组

flags: ACC_PUBLIC, ACC_STATIC 方法是public,static的

Code:

stack=2, locals=1, args_size=1 操作数栈深度2,局部变量表槽个数1,形参个数1

0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;

3: ldc           #3                  // String Hello World

5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V

8: return

LineNumberTable:

line 5: 0

line 6: 8

LocalVariableTable:

Start  Length  Slot  Name   Signature

0       9     0  args   [Ljava/lang/String;

关于操作数栈,和局部变量表

=============

当Java启动一个线程后,JVM就会给该线程创建:

1、虚拟机栈:保存非native方法的调用信息

2、程序计数器:用来保存下次JVM“执行引擎”需要的指令信息

3、本地方法栈:保存native方法的调用信息

当线程运行中,每调用一次非native方法就会在“虚拟机栈”中压入一个“栈帧”,而栈帧结构包括:

1、局部变量表:

有槽位,用来存储方法中的局部变量的数据,槽位从0开始

2、操作数栈:

会根据JVM“执行引擎”的指令来操作被加入其中的数据。操作数栈的数据来源是JVM堆中“运行时常量池,串池”,JVM虚拟机栈的栈帧中的局部变量表。

3、方法返回地址:

当方法运行结束时,返回到哪

4、动态链接

模拟main方法字节码执行过程

===============

1.执行main方法时,JVM会启动一个main线程,则会创建main线程的虚拟机栈,程序计数器,本地方法栈(本次不涉及),虚拟机栈中会创建好局部变量表,操作数栈,且表和栈的大小已经在class文件中确定了。程序计数器记录执行引擎将要执行的指令。

iconst_0指令表示 创建一个常量0,并压入操作数栈中

将操作数栈顶数据存入(istore) 局部变量表槽位1处(_1)

getstatic获取静态变量,并压入操作数栈

ldc是指加载常量池或串池中的常量到  操作数栈中

ldc #3 就是加载“Hello World”到操作数栈中

invokevirtual指令用于调用对象的实例方法。

如invokevirtual #4 调用的是println方法,该方法的对象是0x001,即System.out

该方法的参数即“Hello World”。

所以需要main栈帧中操作数栈中的数据就被清空了。当println执行结束后,其栈帧被释放。

 

后面执行引擎中的GC模块会选择时机工作,清除掉堆中的0x001对应的对象

通过字节码来破解x=x++问题

===============

public class HelloWorld {

public static void main(String[] args) {

int x = 0;

int i = 0;

while (i<4){

x= x++;

i++;

}

System.out.println(x);

}

}

这道题目我曾经很困惑,为啥x不是4,而是0。

现在通过反编译其字节码就可以知道了

最后:学习总结——MyBtis知识脑图(纯手绘xmind文档)

学完之后,若是想验收效果如何,其实最好的方法就是可自己去总结一下。比如我就会在学习完一个东西之后自己去手绘一份xmind文件的知识梳理大纲脑图,这样也可方便后续的复习,且都是自己的理解,相信随便瞟几眼就能迅速过完整个知识,脑补回来。下方即为我手绘的MyBtis知识脑图,由于是xmind文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的MyBtis知识脑图原件(包括上方的面试解析xmind文档)

image

除此之外,前文所提及的Alibaba珍藏版mybatis手写文档以及一本小小的MyBatis源码分析文档——《MyBatis源码分析》等等相关的学习笔记文档,也皆可分享给认可的朋友!

若是想验收效果如何,其实最好的方法就是可自己去总结一下。比如我就会在学习完一个东西之后自己去手绘一份xmind文件的知识梳理大纲脑图,这样也可方便后续的复习,且都是自己的理解,相信随便瞟几眼就能迅速过完整个知识,脑补回来。下方即为我手绘的MyBtis知识脑图,由于是xmind文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的MyBtis知识脑图原件(包括上方的面试解析xmind文档)

[外链图片转存中…(img-nZpQxKTr-1714801113965)]

除此之外,前文所提及的Alibaba珍藏版mybatis手写文档以及一本小小的MyBatis源码分析文档——《MyBatis源码分析》等等相关的学习笔记文档,也皆可分享给认可的朋友!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 12
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值