bilibili-JVM学习笔记14 异常
The Java Virtual Machine Specification - Java SE 8 Edition
JVM学习笔记11 - Java字节码初识
JVM学习笔记12 - 解读笔记11中的attributes
JVM学习笔记13
- exception_table 这里存放的是处理异常的信息
- 每个 exception_table 表项由 start_pc,end_pc,handler_pc,catch_type 组成
- start_pc 和 end_pc 表示在 code 数组中从 start_pc 到 end_pc 处(包含 start_pc ,不包含 end_pc)的指令抛出的异常会由这个表项处理
- handler_pc 表示处理异常的代码的开始处(catch{…})
- catch_type 表示会被处理的异常类型,它指向常量池里的一个异常类,当 catch_type 为 0 时,表示处理所有的异常
P49 异常处理1 try catch
package new_package.jvm.p50;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
public class ExceptionTest1 {
public void test() {
try {
InputStream inputStream = new FileInputStream("test");
ServerSocket serverSocket = new ServerSocket(9998);
serverSocket.accept();
} catch (FileNotFoundException e) {
} catch (IOException e) {
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
}
Classfile /Users/kevin/Documents/opensource/gitee/java-read-sources-sample/target/classes/new_package/jvm/p50/ExceptionTest1.class
Last modified 2020-6-11; size 1081 bytes
MD5 checksum b82ef5a52bdb54b7d6757c95d0b10e5c
Compiled from "ExceptionTest1.java"
public class new_package.jvm.p50.ExceptionTest1
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #15.#35 // java/lang/Object."<init>":()V
#2 = Class #36 // java/io/FileInputStream
#3 = String #23 // test
#4 = Methodref #2.#37 // java/io/FileInputStream."<init>":(Ljava/lang/String;)V
#5 = Class #38 // java/net/ServerSocket
#6 = Methodref #5.#39 // java/net/ServerSocket."<init>":(I)V
#7 = Methodref #5.#40 // java/net/ServerSocket.accept:()Ljava/net/Socket;
#8 = Fieldref #41.#42 // java/lang/System.out:Ljava/io/PrintStream;
#9 = String #43 // finally
#10 = Methodref #44.#45 // java/io/PrintStream.println:(Ljava/lang/String;)V
#11 = Class #46 // java/io/FileNotFoundException
#12 = Class #47 // java/io/IOException
#13 = Class #48 // java/lang/Exception
#14 = Class #49 // new_package/jvm/p50/ExceptionTest1
#15 = Class #50 // java/lang/Object
#16 = Utf8 <init>
#17 = Utf8 ()V
#18 = Utf8 Code
#19 = Utf8 LineNumberTable
#20 = Utf8 LocalVariableTable
#21 = Utf8 this
#22 = Utf8 Lnew_package/jvm/p50/ExceptionTest1;
#23 = Utf8 test
#24 = Utf8 inputStream
#25 = Utf8 Ljava/io/InputStream;
#26 = Utf8 serverSocket
#27 = Utf8 Ljava/net/ServerSocket;
#28 = Utf8 StackMapTable
#29 = Class #46 // java/io/FileNotFoundException
#30 = Class #47 // java/io/IOException
#31 = Class #48 // java/lang/Exception
#32 = Class #51 // java/lang/Throwable
#33 = Utf8 SourceFile
#34 = Utf8 ExceptionTest1.java
#35 = NameAndType #16:#17 // "<init>":()V
#36 = Utf8 java/io/FileInputStream
#37 = NameAndType #16:#52 // "<init>":(Ljava/lang/String;)V
#38 = Utf8 java/net/ServerSocket
#39 = NameAndType #16:#53 // "<init>":(I)V
#40 = NameAndType #54:#55 // accept:()Ljava/net/Socket;
#41 = Class #56 // java/lang/System
#42 = NameAndType #57:#58 // out:Ljava/io/PrintStream;
#43 = Utf8 finally
#44 = Class #59 // java/io/PrintStream
#45 = NameAndType #60:#52 // println:(Ljava/lang/String;)V
#46 = Utf8 java/io/FileNotFoundException
#47 = Utf8 java/io/IOException
#48 = Utf8 java/lang/Exception
#49 = Utf8 new_package/jvm/p50/ExceptionTest1
#50 = Utf8 java/lang/Object
#51 = Utf8 java/lang/Throwable
#52 = Utf8 (Ljava/lang/String;)V
#53 = Utf8 (I)V
#54 = Utf8 accept
#55 = Utf8 ()Ljava/net/Socket;
#56 = Utf8 java/lang/System
#57 = Utf8 out
#58 = Utf8 Ljava/io/PrintStream;
#59 = Utf8 java/io/PrintStream
#60 = Utf8 println
{
public new_package.jvm.p50.ExceptionTest1();
descriptor: ()V
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 14: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lnew_package/jvm/p50/ExceptionTest1;
public void test();
descriptor: ()V
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
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 9998
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 19: 0
line 20: 10
line 21: 21
line 26: 26
line 27: 34
line 22: 37
line 26: 38
line 27: 46
line 23: 49
line 26: 50
line 27: 58
line 24: 61
line 26: 62
line 27: 70
line 26: 73
line 27: 82
line 28: 84
LocalVariableTable:
Start Length Slot Name Signature
10 16 1 inputStream Ljava/io/InputStream;
21 5 2 serverSocket Ljava/net/ServerSocket;
0 85 0 this Lnew_package/jvm/p50/ExceptionTest1;
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 */
}
SourceFile: "ExceptionTest1.java"
解析:
- 采用异常表的方式对异常进行处理
- 存在 finally 语句时,编译器会将 finally 语句块的字节码拼接到每一个 catch 语句字节码之后
- 编译器会自动添加一个 catch 针对 Throwable
- LineNumberTable : 源代码中的行号和字节码中的行号对应关系,可用于 debug
异常处理2 throw
package new_package.jvm.p50;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
public class ExceptionTest2 {
public void test() throws IOException, NullPointerException {
InputStream inputStream = new FileInputStream("test");
ServerSocket serverSocket = new ServerSocket(9998);
serverSocket.accept();
}
}
Classfile /Users/kevin/Documents/opensource/gitee/java-read-sources-sample/target/classes/new_package/jvm/p50/ExceptionTest2.class
Last modified 2020-6-11; size 745 bytes
MD5 checksum c41f2e60a4c96df0c6d75bfa931fa113
Compiled from "ExceptionTest2.java"
public class new_package.jvm.p50.ExceptionTest2
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #9.#27 // java/lang/Object."<init>":()V
#2 = Class #28 // java/io/FileInputStream
#3 = String #17 // test
#4 = Methodref #2.#29 // java/io/FileInputStream."<init>":(Ljava/lang/String;)V
#5 = Class #30 // java/net/ServerSocket
#6 = Methodref #5.#31 // java/net/ServerSocket."<init>":(I)V
#7 = Methodref #5.#32 // java/net/ServerSocket.accept:()Ljava/net/Socket;
#8 = Class #33 // new_package/jvm/p50/ExceptionTest2
#9 = Class #34 // java/lang/Object
#10 = Utf8 <init>
#11 = Utf8 ()V
#12 = Utf8 Code
#13 = Utf8 LineNumberTable
#14 = Utf8 LocalVariableTable
#15 = Utf8 this
#16 = Utf8 Lnew_package/jvm/p50/ExceptionTest2;
#17 = Utf8 test
#18 = Utf8 inputStream
#19 = Utf8 Ljava/io/InputStream;
#20 = Utf8 serverSocket
#21 = Utf8 Ljava/net/ServerSocket;
#22 = Utf8 Exceptions
#23 = Class #35 // java/io/IOException
#24 = Class #36 // java/lang/NullPointerException
#25 = Utf8 SourceFile
#26 = Utf8 ExceptionTest2.java
#27 = NameAndType #10:#11 // "<init>":()V
#28 = Utf8 java/io/FileInputStream
#29 = NameAndType #10:#37 // "<init>":(Ljava/lang/String;)V
#30 = Utf8 java/net/ServerSocket
#31 = NameAndType #10:#38 // "<init>":(I)V
#32 = NameAndType #39:#40 // accept:()Ljava/net/Socket;
#33 = Utf8 new_package/jvm/p50/ExceptionTest2
#34 = Utf8 java/lang/Object
#35 = Utf8 java/io/IOException
#36 = Utf8 java/lang/NullPointerException
#37 = Utf8 (Ljava/lang/String;)V
#38 = Utf8 (I)V
#39 = Utf8 accept
#40 = Utf8 ()Ljava/net/Socket;
{
public new_package.jvm.p50.ExceptionTest2();
descriptor: ()V
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 13: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lnew_package/jvm/p50/ExceptionTest2;
public void test() throws java.io.IOException, java.lang.NullPointerException;
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=3, args_size=1
0: new #2 // class java/io/FileInputStream
3: dup
4: ldc #3 // String test
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 9998
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: return
LineNumberTable:
line 15: 0
line 16: 10
line 17: 21
line 18: 26
LocalVariableTable:
Start Length Slot Name Signature
0 27 0 this Lnew_package/jvm/p50/ExceptionTest2;
10 17 1 inputStream Ljava/io/InputStream;
21 6 2 serverSocket Ljava/net/ServerSocket;
Exceptions:
throws java.io.IOException, java.lang.NullPointerException
}
SourceFile: "ExceptionTest2.java"