一段java代码是如何执行的?
摘要:当你学会了java语言之后,你写了一些代码,然后你想要执行你的代码,来达成某些功能。那么,你都知道这段java代码都是如何执行的吗?
本文分享自华为云社区《一段java代码是如何执行的》,原文作者:技术火炬手 。
当你学会了java语言之后,你写了一些代码,然后你想要执行你的代码,来达成某些功能。那么,你都知道这段代码都是如何执行的吗?
1. 编译成class
众所周知,java代码是不能直接在jvm上执行的,执行的是class文件,将java代码编程class文件,需要编译
常用的编译方法是:javac xxx.java
但目前常见的java编辑工具,如eclipse和ideal都自带自动编译动能
2. jvm的构成
让我们回忆一下jvm的构成:

主题上分为五个部分:
方法区,本地方法栈,java堆,java栈,程序计数器
其中,java栈,本地方法栈,程序计数器为线程私有,其余为线程共享
那么,方法在哪个地方执行呢?
java栈。
栈的遵循的方式是先进后出,java栈中方法的执行也遵循此规律,方法执行的步骤又称为栈帧。
3. 方法的顺序执行和栈帧
上代码:
Java 代码
public class Main {
public static void a(){
b();
}
public static void b(){
c();
}
public static void c(){
System.out.println("Hello world!");
}
public static void main(String[] args) {
a();
}
}
上面是一段很简单的代码,主体上就是:
(1)一个Main类
(2)上面定义了一个main方法
(3)该main方法调用了静态方法a
(4)方法a调用方法b
(5)方法b调用方法c
(6)方法c打印了“Hello world!”
前文说过,java定义的非本地方法都是在java栈内执行的,一方法一栈帧
所以假设
mian方法对应栈帧m
- a方法对应栈帧a
- b方法对应栈帧b
- c方法对应栈帧c
根据方法的调用,入栈顺序为:m,a,b,c
所以,栈帧出栈(即方法执行)顺序为:c,b,a,m
4. class文件反编译过后的样子
上一节,方法或栈帧在java栈的执行顺序,但在方法体内的内容是怎么执行的呢。
前文提到,jvm执行的是class文件,而class文件内是什么?
class文件内是一组指令集。
如何证明呢,还是再看一段代码。
Java 代码
public class Calculator{
public int add(){
int n = 10;
int m = 20;
int r = n + m;
return r;
}
public static void main(String[] args) {
Calculator calculator = new Calculator();
int a = calculator.add();
System.out.println(a);
}
}
如上代码,实现的功能是:
(1)定义两个变量,相加
(2)main方法new对象,调用方法
但,class文件是不可以直接查看的。
我们可以采用反编译的方法,反编译命令:
javap -c xxx.class

上述文件反编译后的样子如下:

每个方法下面的Code,都是一组指令集。
5. 指令集详解
在讨论指令集之前,首先要讲一个概念,那就是对栈帧进一步拆分。
栈帧一共分为四个部分:局部变量表、操作数栈、动态链接、方法返回地址
其中,局部变量表和操作数栈是最重要的两个部分,局部变量表存放在方法中定义的局部变量,操作数栈相当于jvm的一个缓存,所有的操作都必须在此处进行,所有的变量都必须加载到操作数栈才能被使用。所以,所谓指令,就是在局部变量表和操作数栈来回倒腾的过程。
下面对指令进行分类讲解:
(1)入栈指令
整型入栈指令:
- 取值-1~5采用iconst指令;
- 取值-128~127采用bipush指令;
- 取值-32768~32767采用sipush指令;
- 取值-2147483648~2147483647采用ldc指令。
非整型入栈指令:
- float,String类型也使用ldc指令
- double和long类型使用ldc_2w
- boolean类型视作0和1
- null的入栈指令为:aconst_null
(2)存储指令
将操作数栈中的常量保存在局部变量表中的某个位置
如:
- istore_1:将上面入栈的整型常量保存在局部变量表中的第1个位置
- fstore_2:将上面入栈的浮点常量保存在局部变量表中的第2个位置
- dstore_10:将上面入栈的双浮点常量保存在局部变量表中的第10个位置
- lstore_20:将上面入栈的长整常量保存在局部变量表中的第20个位置
- astore_100:将上面入栈的引用常量保存在局部变量表中的第100个位置
(3)变量入栈指令
- iload_1:局部变量表中的第1个位置的整型变量入栈
- fload_2:局部变量表中的第1个位置的浮点型变量入栈
- dload_10:局部变量表中的第1个位置的双浮点型变量入栈
- lload_20:局部变量表中的第1个位置的长整型变量入栈
- aload_100:局部变量表中的第100个位置的引用型变量入栈
(4)计算指令
- 加:iadd、ladd、fadd、dadd
减:isub、lsub、fsub、dsub
乘:imul、lmul、fmul、dmul
除:idiv、ldiv、fdiv、ddiv
注意:栈顶计算,一次只能计算一个表达式
一段java代码是如何执行的?的更多相关文章
- jsp页面:js方法里嵌套java代码(是操作数据库的),如果这个js 方法没被调用,当jsp页面被解析的时候,不管这个js方法有没有被调用这段java代码都会被执行?
jsp页面:js方法里嵌套java代码(是操作数据库的),如果这个js 方法没被调用,当jsp页面被解析的时候,不管这个js方法有没有被调用这段java代码都会被执行? 因为在解析时最新解析的就是JA ...
- JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)
转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...
- Java和操作系统交互(Java 代码是怎么执行)(转)
结合 CPU 理解一行 Java 代码是怎么执行的 根据冯·诺依曼思想,计算机采用二进制作为数制基础,必须包含:运算器.控制器.存储设备,以及输入输出设备,如下图所示. 我们先来分析 CPU 的工作原 ...
- 操作系统 | 结合 CPU 理解一行 Java 代码是怎么执行的
根据冯·诺依曼思想,计算机采用二进制作为数制基础,必须包含:运算器.控制器.存储设备,以及输入输出设备,如下图所示. 我们先来分析 CPU 的工作原理,现代 CPU 芯片中大都集成了,控制单元,运算单 ...
- Java 代码编译和执行的整个过程
Java 代码编译是由 Java 源码编译器来完成,流程图如下所示: Java 字节码的执行是由 JVM 执行引擎来完成,流程图如下所示: Java 代码编译和执行的整个过程包含了以下三个重要的机制: ...
- JVM学习笔记(二)------Java代码编译和执行的整个过程【转】
转自:http://blog.csdn.net/cutesource/article/details/5904542 版权声明:本文为博主原创文章,未经博主允许不得转载. Java代码编译是由Java ...
- JVM学习笔记(二)------Java代码编译和执行的整个过程
Java代码编译是由Java源码编译器来完成,流程图如下所示: Java字节码的执行是由JVM执行引擎来完成,流程图如下所示: Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码 ...
- Java代码编译和执行的整个过程
Java代码编译是由Java源码编译器来完成,流程图如下所示: Java字节码的执行是由JVM执行引擎来完成,流程图如下所示: Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码 ...
- 夯实Java基础系列7:一文读懂Java 代码块和执行顺序
目录 Java中的构造方法 构造方法简介 构造方法实例 例 1 例 2 Java中的几种构造方法详解 普通构造方法 默认构造方法 重载构造方法 java子类构造方法调用父类构造方法 Java中的代码块 ...
- 夯实Java基础系列7:Java 代码块和执行顺序
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
随机推荐
- 使用Github Action实现构建、发布到 nuget.org
使用Github Action实现构建.发布到 nuget.org GitHub Actions是GitHub提供的持续集成和持续部署(CI/CD)工具,它能够自动化构建.测试和部署你的项目.在这篇教 ...
- 如何使用DALL-E 3
如何使用 DALL-E 3:OpenAI 图像生成指南 DALL-E 3 是 OpenAI 图像生成器的高级版本,它可以理解自然语言提示来创建详细图像. 它克服了以前版本的方形图像限制,现在支持各种宽 ...
- fastjson反序列化Map对象为null?其实它只是一个地址,试试Map深拷贝
今天遇到一个小问题,我用fastjson,把一个map对象转为实体类对象返回给前端的时候,map对象里面的一个属性既然为null. 由于前端需求,我们需要返回一个json里面,有两个属性是一样的(都是 ...
- 开发一个现代化的.NetCore控制台程序,包含依赖注入/配置/日志等要素
前言 最近需要开发小工具的场景有点多,上次我用 go 语言开发了一个 hive 导出工具,体验还不错,只是 go 语言的语法实在是喜欢不起来,这次继续试试用 C# 来开发小工具. 这次小工具的功能很简 ...
- 题解 CF1401C
题目大意: 给定一序列 \(A\),定义当且仅当 \(\gcd(a_i,a_j)=a_{min}\) 时,元素 \(a_i\) 和 \(a_j\) 可以交换. 问当前给定的序列 \(A\) 能否转化为 ...
- JavaScript高级程序设计笔记07 迭代器与生成器
迭代器与生成器 1.迭代 反复多次执行一段程序,(有明确的终止条件) 迭代器.生成器 ES6 计数循环(for):最简单的迭代 迭代次数.迭代每次执行的操作 (顺序已知) 古早迭代(有序->数组 ...
- uni-app框架开发app发布流程
uni-app框架开发app发布流程 1.首先公司申请软著 步骤:申请软著详细流程 - 阿长*长 - 博客园 (cnblogs.com) 一.安卓端 1,点击发行>原生-app云打包 正式包和自 ...
- 生产实践:Redis与Mysql的数据强一致性方案
公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享. 数据库和Redis如何保持强一致性,这篇文章告诉你 目的 Redis和Msql来保持数据同步,并且强一致,以此来提高对应接 ...
- HBuilderx 创建 、运行uniapp项目
uni-app官网介绍的 通过 HBuilderX 可视化界面 跟着小颖来创建一个自己的小程序 创建小程序 依次点击HBuilderx 左上方的按钮:文件->新建->项目 然后打开该界面, ...
- SpringBoot进阶教程(七十八)邮件服务
Sun公司提供了JavaMail用来实现邮件发送,但是配置烦琐,Spring中提供了JavaMailSender用来简化邮件配置,Spring Boot则提供了MailSenderAutoConfig ...