关于Java类中的每一个实例方法(非static方法),其在编译后所生成的字节码中,方法参数的数量总是会比源代码方法参数的数量多一个(this),它位于方法的第一个参数位置,这样我们就可以在Java的实例方法中使用this来去访问当前对象属性及其他方法。
这个操作在编译期间完成的,由javac编译器在编译的时候将对this的访问转化为对一个普通实例方法参数的访问,接下来在运行期间,由JVM在调用实例方法时,自动向实例方法传入该this参数,所以,在实例方法的局部变量表中,至少会有一个指向当前对象的局部变量。
Java字节码对于异常的处理方式:
- 统一采用异常表的方式对于异常进行处理
- 在JDK1.4.2之前的版本中并不是采用异常表的方式对异常进行处理的,而是采用特定指令的方式处理的 使用 jsr 和 ret 指令
- 当异常处理存在finally语句块时,现代化的JVM采取的处理方式是将finally语句块的字节码拼接到每一个catch块后面,换句话说,程序中存在多少个catch块就会在每一个catch块后面重复多少个finally语句块的字节码,而后通过goto跳转到return 位置。对于any类型的异常不需要拼接。finally语句块并不是只有一个。
C:\spring_lecture\target\classes\com\compass\spring_lecture\binarycode>javap -v MyTest3
警告: 二进制文件MyTest3包含com.compass.spring_lecture.binarycode.MyTest3
Classfile /C:/spring_lecture/target/classes/com/compass/spring_lecture/binarycode/MyTest3.class
Last modified 2019-7-3; size 1098 bytes
MD5 checksum 25b6ca2c3d65c45c4c1223376c45e3b4
Compiled from "MyTest3.java"
public class com.compass.spring_lecture.binarycode.MyTest3
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 #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/compass/spring_lecture/binarycode/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/compass/spring_lecture/binarycode/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/compass/spring_lecture/binarycode/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.compass.spring_lecture.binarycode.MyTest3();
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 9: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/compass/spring_lecture/binarycode/MyTest3;
public void test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=4, args_size=1
//stack表示操作数栈的最大深度 locals表示局部变量的数目 args_size表示参数的个数。
//args_size=1表示的是this这个关键字(对于java类的成员方法(实例方法))的第1个参数都是隐式的this表示当前的对象。
//在编译的时候已经确定下来了 并不是在运行期间 类似于python中的self。
//locals=4 分别是is 、serverSocket、this、ex(3个catch只能进入一个 )所以ex也是一个局部变量。
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 8989
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 16: 0
line 18: 10
line 20: 21
line 29: 26
line 30: 34
line 22: 37
line 29: 38
line 30: 46
line 24: 49
line 29: 50
line 30: 58
line 26: 61
line 29: 62
line 30: 70
line 29: 73
line 30: 82
line 31: 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/compass/spring_lecture/binarycode/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 */
}
SourceFile: "MyTest3.java"
上面介绍的是关于catch异常的字节码体现,下面看一下关于显示的异常throws字节码是如何体现的?
Exceptions:
throws java.lang.NullPointerException, java.io.IOException, java.io.FileNotFoundException
jclasslib中查看一下:
显示抛出异常
网友评论