通过字节码分析java中的switch语句
在一次做题中遇到了switch的问题,由于对switch执行顺序的不了解,在这里简单的通过字节码的方式理解一下switch执行顺序(题目如下):
public class Ag{
static public int i=10;
public static void main(String []args){
switch(i){
default:
System.out.println("this is default");
case 1:
System.out.println("this is one");
case 2:
System.out.println("this is two");
case 10:
System.out.println("this is ten");
case 5:
System.out.println("this is five");
}
}
}
输出为:

下面通过例子来分析一下switch:
一、首先代码1如截图所示:

简单说一下代码,代码很简单,就是在一个类中建一个main方法,然后在main方法中使用一个switch语句(注意了,这个代码中default在最前面),然后通过javap工具获取字节码,进而对switch的执行方式进行分析,得到的字节码截图如下:

字节码分析如下:
public static void main(java.lang.String[]);
Code:
0: iconst_5//将常量5进入操作栈
1: istore_1//将栈顶数据存入局部变量1
2: iload_1//将第一个局部变量入栈
3: lookupswitch { // 2 //出现switch那必然是switch语句了
1: 33 //当a==1时,执行标号33的语句
2: 38 //当a==2时,执行标号38的语句
default: 28 //default情况下,虽然语句在前面,但是判断依然最后判断,执行标号28的语句
}
28: iconst_5 //开始执行default里面的内容
29: istore_2 //28和29语句类似于int b =5
30: goto 43 //由于使用了break,跳出了语句,所以执行语句43,也就是跳出了switch,下同
33: iconst_5//开始执行a==1时的操作
34: istore_2
35: goto 43 //如果不用break,将继续执行接下来的语句,而不是跳出switch
38: iconst_5 //开始执行a==1时的操作</span>
39: istore_2
40: goto 43
43: return //main方法执行结束
二、第二个测试代码(default放到了最后面):

同样的简单说一下代码,代码很简单,就是在一个类中建一个main方法,然后在main方法中使用一个switch语句(注意了,这个代码中default在最后面),然后通过javap工具获取字节码,进而对switch的执行方式进行分析,得到的字节码截图如下:

字节码分析如下,只需关注两次代码中字节码的异同点:
public static void main(java.lang.String[]);
Code:
0: iconst_5
1: istore_1
2: iload_1
3: lookupswitch { //
1: 28
2: 33
default: 38 //值得注意的是default依然在最后面,唯一变化的就是执行语句的位置
}
28: iconst_5 //a==1语句的执行位置
29: istore_2
30: goto 43
33: iconst_5 //a==2语句执行的位置
34: istore_2
35: goto 43
38: iconst_5 //default语句执行的位置
39: istore_2
40: goto 43
43: return
}
总结:
从上面的两个代码中可以得到:
1、不管switch中default位置如何,它都是最后一个进行判断的;
2、虽然default是最后一个进行判断的,但是default中的语句的位置依然和default在句中的位置有关(这句话接近于废话,但是,当case语句中没有break时,整个switch也就类似于顺序的去执行)
3、当case中没有break时,它的执行顺序和执行方式就是继续向下执行,直到switch结束或者遇到break。
最后来一个小例子测试一下对本文的分析(怎么这么眼熟,对,就是最开始的那个代码稍微改了一点):
public class Ag{
static public int i=10;
public static void main(String []args){
switch(i){
default:
System.out.println("this is default");
case 1:
System.out.println("this is one");
case 2:
System.out.println("this is two");
case 5:
System.out.println("this is five");
}
}
}
结果就不用说了。
通过字节码分析java中的switch语句的更多相关文章
- 从字节码看java中 this 的隐式传参
从字节码看java中 this 隐式传参具体体现(和python中的self如出一辙,但是比python中藏得更深),也发现了 static 与 非 static 方法的区别所在! static与非s ...
- Java中的switch语句后面的控制表达式的数据类型
Java中的switch语句后面的控制表达式的数据类型 1.byte 2.char 3.short 4.int 5.枚举类型 6.Java 7允许java.lang.String类型
- 通过字节码分析Java方法的静态分派与动态分派机制
在上一次[https://www.cnblogs.com/webor2006/p/9723289.html]中已经对Java方法的静态分派在字节码中的表现了,也就是方法重载其实是一种静态分派的体现,这 ...
- 通过字节码分析Java异常处理机制
在上一次[https://www.cnblogs.com/webor2006/p/9691523.html]初步对异常表相关的概念进行了了解,先来回顾一下: 其源代码也贴一下: 下面来看一下jclas ...
- 透过字节码分析java基本类型数组的内存分配方式。
我们知道java中new方式创建的对象都是在堆中创建的,而局部变量对应的值存放在栈上.那么java中的int [] arr={1,2,3}是存放在什么地方的呢,int []arr = new int[ ...
- Java中的switch语句——通过示例学习Java编程(8)
作者:CHAITANYA SINGH 来源:https://www.koofun.com//pro/kfpostsdetail?kfpostsid=19 当我们在代码逻辑中有多个选项,而且需要为每个选 ...
- 透过字节码分析Java动态代理机制。
一.创建动态代理代码 1.创建接口 public interface Subject { void request(); } 2.创建接口实现类 public class RealSubject im ...
- Java中的switch语句
switch可以替代if..else..,另外据说switch采用二分搜索,效率会更高一点. switch(type) { case 1 : type_name="INCOMING" ...
- Java并发编程原理与实战八:产生线程安全性问题原因(javap字节码分析)
前面我们说到多线程带来的风险,其中一个很重要的就是安全性,因为其重要性因此,放到本章来进行讲解,那么线程安全性问题产生的原因,我们这节将从底层字节码来进行分析. 一.问题引出 先看一段代码 packa ...
随机推荐
- WPF中获取鼠标相对于屏幕的位置
原文:WPF中获取鼠标相对于屏幕的位置 WPF中获取鼠标相对于屏幕的位置 周银辉WPF编程时,我们经常使用Mouse.GetPosi ...
- QT的进程与线程(cmd /c的写法)
该文章原创于Qter开源社区(www.qter.org),作者yafeilinux,转载请注明出处! 导语 在前面的几节内容中讲解了Qt网络编程的一些基本内容,这一节来看一下在Qt中进程和线程的基本应 ...
- tensorflow 1.0 学习:模型的保存与恢复
将训练好的模型参数保存起来,以便以后进行验证或测试,这是我们经常要做的事情.tf里面提供模型保存的是tf.train.Saver()模块. 模型保存,先要创建一个Saver对象:如 saver=tf. ...
- Win10《芒果TV》商店版双十一独家大礼,每日前100名用户免费领取7天VIP
为答谢大家对Win10<芒果TV>商店版一年以来一如既往的支持,2016年11月1日-11月30日期间,每天登录<芒果TV>UWP版(最新版本v3.1.3)的前100位用户可领 ...
- 图形界面编程成就了C++
听有人说C#.VB比C++好是因为做界面方便还算傻得可爱,听有人说用C++做数值计算而不屑于做界面可就对不起咱C++的恩人了.这我可要说道说道. 想当年C++刚出江湖,名门出身,自立门派,想抢Obje ...
- C#WinForm线程基类
在CS模式开发中一般我们需要用到大量的线程来处理比较耗时的操作,以防止界面假死带来不好的体验效果,下面我将我定义的线程基类给大家参考下,如有问题欢迎指正. 基类代码 #region 方法有返回值 // ...
- 使用 acl 编写 UDP 网络程序(UDP 重传及可靠性机制)
在当今网络世界,虽然大部分网络应用都是基于 TCP 的,但有时 UDP 的网络通信也有用武之处.acl 的网络库中不仅提供了基于 TCP 的网络套接字流,同时也提供了 UDP 的网络库(目前 acl ...
- 可视化流程设计——流程设计器演示(基于Silverlight)
上一篇文章<通用流程设计>对鄙人写的通用流程做了一定的介绍,并奉上了相关源码.但一个好的流程设计必少不了流程设计器的支持,本文将针对<通用流程设计>中的流程的设计器做一个简单的 ...
- 原创powershell脚本:通过远程桌面3389黑名单,阻止黑客ip
远程桌面 3389 ban ip 防火墙 rdp 通过远程桌面3389黑名单,阻止黑客ip.这是一个常见的需求.但我搜遍了谷歌也找不到成品脚本.想做搬运工却做不成,只能自己费尽写.下载备用吧,估计 ...
- 编解码器之战:AV1、HEVC、VP9和VVC
视频Codec专家Jan Ozer在Streaming Media West上主持了一场开放论坛,邀请百余名观众参与热门Codec的各项优势与短板.本文整理了讨论的主要成果,基本代表了AV1.HEVC ...