1、创建MyTest3类

public class MyTest3 {

    public void test(){
try {
InputStream is = new FileInputStream("test.txt"); ServerSocket serverSocket = new ServerSocket(9999);
serverSocket.accept();
}catch (FileNotFoundException ex){ }catch (IOException ex){ } catch (Exception ex){ }finally {
System.out.println("finally");
}
}
}

  然后生成字节码

D:\workspace\study\ jvm_demo\build\classes\java\main\com\example\jvm\bytecode>javap -verbose MyTest3.class

Classfile /D:/workspace/study/ jvm_demo/build/classes/java/main/com/example/jvm/bytecode/MyTest3.class
Last modified 2019-6-29; size 1068 bytes
MD5 checksum a51a76cf80a500bc95a8d3d20f7d2a0e
Compiled from "MyTest3.java"
public class com.example.jvm.bytecode.MyTest3
SourceFile: "MyTest3.java"
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #15.#35 // java/lang/Object."<init>":()V
#2 = Class #36 // java/io/FileInputStream
#3 = String #37 // test.txt
#4 = Methodref #2.#38 // java/io/FileInputStream."<init>":(Ljava/lang/String;)V
#5 = Class #39 // java/net/ServerSocket
#6 = Methodref #5.#40 // java/net/ServerSocket."<init>":(I)V
#7 = Methodref #5.#41 // java/net/ServerSocket.accept:()Ljava/net/Socket;
#8 = Fieldref #42.#43 // java/lang/System.out:Ljava/io/PrintStream;
#9 = String #44 // finally
#10 = Methodref #45.#46 // java/io/PrintStream.println:(Ljava/lang/String;)V
#11 = Class #47 // java/io/FileNotFoundException
#12 = Class #48 // java/io/IOException
#13 = Class #49 // java/lang/Exception
#14 = Class #50 // com/example/jvm/bytecode/MyTest3
#15 = Class #51 // java/lang/Object
#16 = Utf8 <init>
#17 = Utf8 ()V
#18 = Utf8 Code
#19 = Utf8 LineNumberTable
#20 = Utf8 LocalVariableTable
#21 = Utf8 this
#22 = Utf8 Lcom/example/jvm/bytecode/MyTest3;
#23 = Utf8 test
#24 = Utf8 is
#25 = Utf8 Ljava/io/InputStream;
#26 = Utf8 serverSocket
#27 = Utf8 Ljava/net/ServerSocket;
#28 = Utf8 StackMapTable
#29 = Class #47 // java/io/FileNotFoundException
#30 = Class #48 // java/io/IOException
#31 = Class #49 // java/lang/Exception
#32 = Class #52 // java/lang/Throwable
#33 = Utf8 SourceFile
#34 = Utf8 MyTest3.java
#35 = NameAndType #16:#17 // "<init>":()V
#36 = Utf8 java/io/FileInputStream
#37 = Utf8 test.txt
#38 = NameAndType #16:#53 // "<init>":(Ljava/lang/String;)V
#39 = Utf8 java/net/ServerSocket
#40 = NameAndType #16:#54 // "<init>":(I)V
#41 = NameAndType #55:#56 // accept:()Ljava/net/Socket;
#42 = Class #57 // java/lang/System
#43 = NameAndType #58:#59 // out:Ljava/io/PrintStream;
#44 = Utf8 finally
#45 = Class #60 // java/io/PrintStream
#46 = NameAndType #61:#53 // println:(Ljava/lang/String;)V
#47 = Utf8 java/io/FileNotFoundException
#48 = Utf8 java/io/IOException
#49 = Utf8 java/lang/Exception
#50 = Utf8 com/example/jvm/bytecode/MyTest3
#51 = Utf8 java/lang/Object
#52 = Utf8 java/lang/Throwable
#53 = Utf8 (Ljava/lang/String;)V
#54 = Utf8 (I)V
#55 = Utf8 accept
#56 = Utf8 ()Ljava/net/Socket;
#57 = Utf8 java/lang/System
#58 = Utf8 out
#59 = Utf8 Ljava/io/PrintStream;
#60 = Utf8 java/io/PrintStream
#61 = Utf8 println
{
public com.example.jvm.bytecode.MyTest3();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 9: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/example/jvm/bytecode/MyTest3; public void test();
flags: ACC_PUBLIC
Code:
stack=3, locals=4, args_size=1
0: new #2 // class java/io/FileInputStream
3: dup
4: ldc #3 // String test.txt
6: invokespecial #4 // Method java/io/FileInputStream."<init>":(Ljava/lang/String;)V
9: astore_1
10: new #5 // class java/net/ServerSocket
13: dup
14: sipush 9999
17: invokespecial #6 // Method java/net/ServerSocket."<init>":(I)V
20: astore_2
21: aload_2
22: invokevirtual #7 // Method java/net/ServerSocket.accept:()Ljava/net/Socket;
25: pop
26: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
29: ldc #9 // String finally
31: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
34: goto 84
37: astore_1
38: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
41: ldc #9 // String finally
43: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
46: goto 84
49: astore_1
50: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
53: ldc #9 // String finally
55: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
58: goto 84
61: astore_1
62: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
65: ldc #9 // String finally
67: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
70: goto 84
73: astore_3
74: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
77: ldc #9 // String finally
79: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
82: aload_3
83: athrow
84: return
Exception table:
from to target type
0 26 37 Class java/io/FileNotFoundException
0 26 49 Class java/io/IOException
0 26 61 Class java/lang/Exception
0 26 73 any
LineNumberTable:
line 13: 0
line 15: 10
line 16: 21
line 24: 26
line 25: 34
line 17: 37
line 24: 38
line 25: 46
line 19: 49
line 24: 50
line 25: 58
line 21: 61
line 24: 62
line 25: 70
line 24: 73
line 26: 84
LocalVariableTable:
Start Length Slot Name Signature
10 16 1 is Ljava/io/InputStream;
21 5 2 serverSocket Ljava/net/ServerSocket;
0 85 0 this Lcom/example/jvm/bytecode/MyTest3;
StackMapTable: number_of_entries = 5
frame_type = 101 /* same_locals_1_stack_item */
stack = [ class java/io/FileNotFoundException ]
frame_type = 75 /* same_locals_1_stack_item */
stack = [ class java/io/IOException ]
frame_type = 75 /* same_locals_1_stack_item */
stack = [ class java/lang/Exception ]
frame_type = 75 /* same_locals_1_stack_item */
stack = [ class java/lang/Throwable ]
frame_type = 10 /* same */ }

  查看test方法

stack=3:表示操作数栈的最大深度为3

locals=4: 声明的局部变量的数目为4

args_size=1:  方法本身接收到的参数的数量

思考1:test方法没有接收参数,但是args_size=1表示接收参数为1 ?

对于Java类中的每一实例方法(非static方法),其在编译后所生成的字节码当中,方法参数的数量总是会比源代码中方法参数的数量多一个(this),它位于方法的第一个参数位置处; 这样,我们就可以在Java的实例方法中使用this来去访问当前对象的属性以及其他方法。

  这个操作是在编译期间完成的,即由javac编译期在编译的时候将对this的访问转化为对一个普通实例方法参数的访问,接下来在运行期间,由JVM在调用实例方法时,自动向实例方法传入this参数。所以,在实例方法的局部表里表中,至少会有一个指向当前对象的局部变量。

思考2: locals=4,声明的局部变量的数目为4,分别是哪4个?

this,is, serverSocket,ex

stack=3,操作数栈的最大深度

2、异常表
如下图的三个异常

Java字节码对于异常的处理方式:
1、统一采用异常表的方式来对异常进行处理
2、在jdk1.4.2之前的的版本中,并不是对异常表的方式来对异常进行处理的,而是采用特定的指令方式
3、当异常处理存在finally语句块时,现代化的JVM采取的处理方式是将finally语句块的字节码拼接到每一个catch块后面
换句话说,程序中存在多少个catch块,就会在每一个catch块后面重复多少个finally语句的字节码

然后在方法里抛出异常,

反编译后查看

												

通过字节码分析this关键字以及异常表的作用的更多相关文章

  1. 通过字节码分析this关键字以及异常表的重要作用

    在之前的字节码分析中缺少对异常的介绍,这次主要来对字节码异常表相关的东东进行一个学习,下面先来编写一个相关异常的小程序: 接着编译来看用javap -verbose来查看一下它的字节码信息: xion ...

  2. 通过字节码分析Java异常处理机制

    在上一次[https://www.cnblogs.com/webor2006/p/9691523.html]初步对异常表相关的概念进行了了解,先来回顾一下: 其源代码也贴一下: 下面来看一下jclas ...

  3. JVM-String比较-字节码分析

    一道String字符串比较问题引发的字节码分析 public class a { public static void main(String[] args)throws Exception{ } p ...

  4. Java并发编程原理与实战八:产生线程安全性问题原因(javap字节码分析)

    前面我们说到多线程带来的风险,其中一个很重要的就是安全性,因为其重要性因此,放到本章来进行讲解,那么线程安全性问题产生的原因,我们这节将从底层字节码来进行分析. 一.问题引出 先看一段代码 packa ...

  5. Python_Tips[2] -> 函数延后估值及字节码分析

    函数延后估值及字节码分析 在一个循环中定义了函数 f 但是并未对其进行调用,在循环结束后调用,此时i值为3故最终3个函数输出均为9.而非1, 4, 9. 这是由于在定义闭包函数 f 时,传入变量 i, ...

  6. Java字节码分析

    目录 Java字节码分析 查看字节码详细内容 javap 实例分析 Java字节码分析 对于源码的效率,但从源码来看有时无法分析出准确的结果,因为不同的编译器版本可能会将相同的源码编译成不同的字节码, ...

  7. 通过字节码分析java中的switch语句

    在一次做题中遇到了switch的问题,由于对switch执行顺序的不了解,在这里简单的通过字节码的方式理解一下switch执行顺序(题目如下): public class Ag{ static pub ...

  8. Java finally语句到底是在return之前还是之后执行(JVM字节码分析及内部体系结构)?

    之前看了一篇关于"Java finally语句到底是在return之前还是之后执行?"这样的博客,看到兴致处,突然博客里的一个测试用例让我产生了疑惑. 测试用例如下: public ...

  9. 字节码分析finally块对return返回值的影响

    直接进入主题.看如下代码: public int test(){ int i=0; try { i=1; return i; } catch (Exception e) { i=2; return i ...

随机推荐

  1. 腿部——哑铃&杠铃

  2. redhat6.7 yum网络源配置

    RedHat自带的yum源需要当前系统注册了RHN才可以使用,如果没有注册,当使用yum时,会提示需要注册RHN 如果没有注册RHN,则意味着我们不能使用RedHat自带的yum源.这个时候,我们可以 ...

  3. 阿里云ECS服务器设置端口(允许访问设置)

    1.登录阿里云找到对应的服务器按照如下箭头指示: 2.点击“安全组配置”后进入到如下界面,点击“配置规则”进入详情配置界面. 3.点击“修改”可对特定的端口进行访问配置,如下图: 至此结束.

  4. Flink原理(七)——动态表(Dynamic tables)

    前言 本文是结合Flink官网,个人理解所得,若是有误欢迎留言指出,谢谢!文中图皆来自官网(链接[1]). 本文将随着下面这个问题展开,针对该问题更为生动的解释可以参见金竹老师的分享(链接[2]). ...

  5. Ajax -异步请求 -jquery中ajax分类 -第一层 $.ajax -第二层($.get /$.post) -第三层($.getJson/$.getScript) -相应演示

    Ajax 1.标准请求响应时浏览器的动作(同步操作) 1.1浏览器请求什么资源,跟随显示什么资源2.ajax:异步请求. 2.1局部刷新,通过异步请求,请求到服务器资源数据后,通过脚本修改页面中部分内 ...

  6. python网络-动态Web服务器案例(30)

    一.浏览器请求HTML页面的过程 了解了HTTP协议和HTML文档,其实就明白了一个Web应用的本质就是: 浏览器发送一个HTTP请求: 服务器收到请求,生成一个HTML文档: 服务器把HTML文档作 ...

  7. service worker(二)之主页面与service worker通信

    实现一个主页面发送消息,worker搜到信息向所有的页面派发消息(当前页面除外) msg.html <!DOCTYPE html> <html lang="en" ...

  8. python爬虫——数据爬取和具体解析

    关于正则表达式的更多用法,可参考链接:https://blog.csdn.net/weixin_40040404/article/details/81027081 一.正则表达式: 1.常用正则匹配: ...

  9. quiver()函数

    1.quiver函数 一般用于绘制二维矢量场图,函数调用方法如下: 1 quiver(x,y,u,v) 该函数展示了点(x,y)对应的的矢量(u,v).其中,x的长度要求等于u.v的列数,y的长度要求 ...

  10. spark如何划分DAG视图

    spark根据宽依赖进行DAG视图的划分. 1.窄依赖:每个父RDD的partition 最多被一个子RDD的 partition使用. 窄依赖分为两类:第一类是一对一的依赖关系,在Spark中用On ...