work hard work smart

专注于Java后端开发。 不断总结,举一反三。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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语句的字节码


然后在方法里抛出异常,

反编译后查看