美文网首页工作生活
JVM_字节码:this关键字及异常表字节码分析

JVM_字节码:this关键字及异常表字节码分析

作者: CalmHeart | 来源:发表于2019-07-03 23:46 被阅读0次

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

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

Java字节码对于异常的处理方式:

  1. 统一采用异常表的方式对于异常进行处理
  2. 在JDK1.4.2之前的版本中并不是采用异常表的方式对异常进行处理的,而是采用特定指令的方式处理的 使用 jsr 和 ret 指令
  3. 当异常处理存在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中查看一下:

显示抛出异常

相关文章

网友评论

    本文标题:JVM_字节码:this关键字及异常表字节码分析

    本文链接:https://www.haomeiwen.com/subject/uykocctx.html