浅谈一段java代码是如何执行的

 更新时间:2021年04月06日 10:22:40   作者:华为云  
这篇文章主要介绍了浅谈一段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. 方法的顺序执行和栈帧

上代码:

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方法对应栈帧ab方法对应栈帧bc方法对应栈帧c

根据方法的调用,入栈顺序为:m,a,b,c

所以,栈帧出栈(即方法执行)顺序为:c,b,a,m

4. class文件反编译过后的样子

上一节,方法或栈帧在java栈的执行顺序,但在方法体内的内容是怎么执行的呢。

前文提到,jvm执行的是class文件,而class文件内是什么?

class文件内是一组指令集。

如何证明呢,还是再看一段代码。

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指令。

非整型入栈指令:

  1. float,String类型也使用ldc指令
  2. double和long类型使用ldc_2w
  3. boolean类型视作0和1
  4. 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代码是如何执行的的文章就介绍到这了,更多相关java代码执行内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实力弹弹球实现代码

    Java实力弹弹球实现代码

    这篇文章主要为大家详细介绍了Java实力弹弹球实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • Java中HashMap和HashSet的高效使用技巧分享

    Java中HashMap和HashSet的高效使用技巧分享

    这篇文章主要为大家详细介绍了Java中HashMap和HashSet的高效使用技巧,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • Springboot导出文件,前端下载文件方式

    Springboot导出文件,前端下载文件方式

    这篇文章主要介绍了Springboot导出文件,前端下载文件方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java中的线程池ThreadPoolExecutor细致讲解

    Java中的线程池ThreadPoolExecutor细致讲解

    这篇文章主要介绍了Java中的线程池ThreadPoolExecutor细致讲解,线程池是一种基于池化思想管理线程的工具,经常出现在多线程服务器中,如MySQL,线程过多会带来额外的开销,其中包括创建销毁线程的开销、调度线程的开销等等,需要的朋友可以参考下
    2023-11-11
  • java 实现DES 加密解密的示例

    java 实现DES 加密解密的示例

    这篇文章主要介绍了java 实现DES 加密解密的示例代码,帮助大家更好的理解和使用Java进行加解密,感兴趣的朋友可以了解下
    2020-12-12
  • SpringBoot中的依赖管理详解

    SpringBoot中的依赖管理详解

    这篇文章主要介绍了SpringBoot中的依赖管理详解,传统的Spring框架实现一个Web服务,需要导入各种依赖JAR包,然后编写对应的XML配置文件等,相较而言,Spring Boot显得更加方便、快捷和高效,需要的朋友可以参考下
    2023-08-08
  • Java8 Stream对两个 List 遍历匹配数据的优化处理操作

    Java8 Stream对两个 List 遍历匹配数据的优化处理操作

    这篇文章主要介绍了Java8 Stream对两个 List 遍历匹配数据的优化处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Collection stream使用示例详解

    Collection stream使用示例详解

    这篇文章主要介绍了Collection stream使用示例,stream流几乎可以完成对集合的任意操作,映射、去重、分组、排序、过滤等
    2022-12-12
  • SpringBoot基本web开发demo过程解析

    SpringBoot基本web开发demo过程解析

    这篇文章主要介绍了SpringBoot基本web开发demo过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java完美实现2048小游戏

    Java完美实现2048小游戏

    本文给大家分享的是一则根据网友的代码改编的2048小游戏的源码,个人认为已经非常完美了,推荐给大家,有需要的小伙伴可以参考下。
    2015-03-03

最新评论