通过字节码分析switch语句的执行

简介: 通过字节码分析switch语句的执行

先看一段代码

public class Test {
    public static void main(String[] args) {
        int i = 7;
        switch (i) {
            case 1:
                System.out.println("1");
            default:
                System.out.println("2");
            case 3:
                System.out.println("3");
        }
    }
}

运行结果
2
3


通过javap -c Test.class查看字节码文件

Compiled from "Test.java"
public class com.rsms.iot.service.Test {
  public com.rsms.iot.service.Test();
    Code:
       0: aload_0                //加载一个对象引用到操作数栈,在这里第一个变量是this,所以是将this引用压到操作数栈
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V (构造方法、私有方法和父类中的方法)
       4: return
  public static void main(java.lang.String[]);
    Code:
       0: bipush        7    //将操作数7压到操作数栈中
       2: istore_1     //将整形数字存储到本地变量中
       3: iload_1      //i代表int,从局部变量数组中加载一个对象引用到操作数栈的栈顶
       4: lookupswitch  { // 2   
                     1: 32   //为1匹配32行
                     3: 48   //同上
               default: 40   //同上
          }
      32: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      35: ldc           #3                  // String 1
      37: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      40: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      43: ldc           #5                  // String 2
      45: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      48: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      51: ldc           #6                  // String 3
      53: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      56: return
}


先分析下字节码文件(局部变量表和操作数栈都属于当前栈帧,内存模型我在CSDN一篇博客中整理过:https://mp.csdn.net/postedit/68945933


0:aload_0   会将this变量压到操作数栈中


0: bipush   初始化将变量推送至操作数栈栈顶


2: istore_1 将整形变量存储到本地局部变量表中位置为1的变量中


3: iload_1  将局部变量表中位置为1的变量的引用压到操作数栈中(个人理解是每次调用都会将变量的引用进行一次操作数栈的压栈操作),比如如下代码会有一次istore_1指令,两次iload_1指令。


int i = 7;
System.out.println(i);
System.out.println(i);


image.png


指令执行图示


从字节码文件可以看出,即使default在中间,编译后还是会在最后。所以匹配不到1、3时执行default,跳转到40行,40print执行之后,由于没有break语句,所以会顺序往下执行,会继续执行40行之后的所有语句。


相关文章
|
2月前
|
Python
循环结构程序设置
循环结构程序设置
20 0
|
2月前
|
机器学习/深度学习 人工智能 算法
21.C语言:if语句编译选择结构举例
21.C语言:if语句编译选择结构举例
13 0
|
6天前
|
存储 索引
操作数栈的字节码指令执行分析
操作数栈的字节码指令执行分析
|
6月前
|
Java
Java中的条件语句:if语句和switch语句的作用与区别
Java中的条件语句:if语句和switch语句的作用与区别
141 0
|
6月前
|
Java
Java的流程控制(选择结构语句 if ~ switch &循环结构语句dowhile ~ for)
程序执行的控制流程分为三种,也称为三种结构,分别是:顺序结构、和循环结构。 顺序结构指的是程序执行按照代码的编写顺序,依次从上往下开始执行,直到程序结束。程序的执行默认是顺序执行的
44 1
|
2月前
|
存储 Java 容器
深入Java核心:变量、循环与条件语句的魔法
深入Java核心:变量、循环与条件语句的魔法
13 0
|
9月前
|
人工智能
循环结构 程序举例
循环结构 程序举例
43 0
|
11月前
|
测试技术
c中分支结构程序
c中分支结构程序
|
编译器 C++
有的编译器,for (i=1; i 《 1; i++)会执行循环体
有的编译器,for (i=1; i 《 1; i++)会执行循环体
53 0