摘要:当你学会了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代码是如何执行的?的更多相关文章

  1. jsp页面:js方法里嵌套java代码(是操作数据库的),如果这个js 方法没被调用,当jsp页面被解析的时候,不管这个js方法有没有被调用这段java代码都会被执行?

    jsp页面:js方法里嵌套java代码(是操作数据库的),如果这个js 方法没被调用,当jsp页面被解析的时候,不管这个js方法有没有被调用这段java代码都会被执行? 因为在解析时最新解析的就是JA ...

  2. JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)

    转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...

  3. Java和操作系统交互(Java 代码是怎么执行)(转)

    结合 CPU 理解一行 Java 代码是怎么执行的 根据冯·诺依曼思想,计算机采用二进制作为数制基础,必须包含:运算器.控制器.存储设备,以及输入输出设备,如下图所示. 我们先来分析 CPU 的工作原 ...

  4. 操作系统 | 结合 CPU 理解一行 Java 代码是怎么执行的

    根据冯·诺依曼思想,计算机采用二进制作为数制基础,必须包含:运算器.控制器.存储设备,以及输入输出设备,如下图所示. 我们先来分析 CPU 的工作原理,现代 CPU 芯片中大都集成了,控制单元,运算单 ...

  5. Java 代码编译和执行的整个过程

    Java 代码编译是由 Java 源码编译器来完成,流程图如下所示: Java 字节码的执行是由 JVM 执行引擎来完成,流程图如下所示: Java 代码编译和执行的整个过程包含了以下三个重要的机制: ...

  6. JVM学习笔记(二)------Java代码编译和执行的整个过程【转】

    转自:http://blog.csdn.net/cutesource/article/details/5904542 版权声明:本文为博主原创文章,未经博主允许不得转载. Java代码编译是由Java ...

  7. JVM学习笔记(二)------Java代码编译和执行的整个过程

    Java代码编译是由Java源码编译器来完成,流程图如下所示: Java字节码的执行是由JVM执行引擎来完成,流程图如下所示: Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码 ...

  8. Java代码编译和执行的整个过程

    Java代码编译是由Java源码编译器来完成,流程图如下所示: Java字节码的执行是由JVM执行引擎来完成,流程图如下所示: Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码 ...

  9. 夯实Java基础系列7:一文读懂Java 代码块和执行顺序

    目录 Java中的构造方法 构造方法简介 构造方法实例 例 1 例 2 Java中的几种构造方法详解 普通构造方法 默认构造方法 重载构造方法 java子类构造方法调用父类构造方法 Java中的代码块 ...

  10. 夯实Java基础系列7:Java 代码块和执行顺序

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

随机推荐

  1. Nginx惊群现象的两种解决办法

    惊群现象: 惊群现象是指由多个worker进程监听同一个Socket事件时,当事件发生时,相关的所有进程被惊醒,但最终只能有一个进程对该事件进行处理,其他进程会重新休眠,从而导致系统资源的浪费和系统性 ...

  2. 浅析 C# Console 控制台为什么也会卡死

    一:背景 1. 讲故事 在分析旅程中,总会有几例控制台的意外卡死导致的生产事故,有经验的朋友都知道,控制台卡死一般是动了 快速编辑窗口 的缘故,截图如下: 虽然知道缘由,但一直没有时间探究底层原理,市 ...

  3. Unity禁止C#自动编译

    基于unity2017\2020版本 using System; using System.Linq; using System.Reflection; using UnityEditor; usin ...

  4. python 远程操作svn

    SVN操作脚本 安装模块 pip install pywinrm 脚本如下 #!/usr/bin/env python3 # coding=utf-8 # author:LJX # describe: ...

  5. 51单片机控制w5500实现udp组播通信

    51单片机控制w5500实现udp组播通信 在socket打开之前,向Sn_MR (Socket n 模式寄存器)寄存中写入 0x82(1000 0010),将W5500加入组播组 对Sn_DIPR ...

  6. 七个很实用的开源项目「GitHub 热点速览」

    本周特推的两个项目都是异常实用的项目,一个接棒上周的视频重制项目 video-retalking 这次则是直接将视频替换成另外一个语种:另外一个则是解决日志阅读问题的 tailspin,让你在成千上万 ...

  7. HDL刷题:Count clock

    原题链接 要写一个12小时的时钟. 由题目得知,reset信号的优先级最高,其次是enable,这里很好实现. 我的思路: 写了一个4位的bcd计数器,并实例化了4个,对ss与mm的[7:4]与[3: ...

  8. python之猜数字小游戏

    import random#随机数函数 a = random.randint(0, 50)#随机0-50之内的整数 print('------------------SWS工作室----------- ...

  9. C#/.NET/.NET Core推荐学习书籍(已分类)

    前言 古人云:"书中自有黄金屋,书中自有颜如玉",说明了书籍的重要性.作为程序员,我们需要不断学习以提升自己的核心竞争力.以下是一些优秀的C#/.NET/.NET Core相关学习 ...

  10. JAVA学习9/29

    1.继承extends//关键字 1.1.测试:子类继承父类后,能使用子类对象调用父类方法吗? 可以,因为子类继承父类后,这个该方法就属于子类了. 当然可以使用子类对象来调用 1.2.在实际开发中,满 ...