【jvm】虚拟机栈之动态链接

目录

一、说明
  • 1.指向运行时常量池的方法引用
  • 2.每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用
  • 3.包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接(Dynamic Linking)
  • 4.在java源文件被编译到字节码文件中时,所有的变量和方法引用都作为符号引用(Symbolic Reference)保存在class文件的常量池里。比如:描述一个方法调用了另外的其他方法时,就是通过常量池中指向方法的符号引用来表示的
  • 5.动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用
二、代码示例
package com.learning.stack.dynamic_linking;

/**
 * @Author wangyouhui
 * @Description 动态链接
 **/
public class DynamicLinkingTest {
    int num = 10;

    public void methodOne(){
        System.out.println("方法1执行了");
        methodTwo();
        num++;
    }

    public void methodTwo(){
        System.out.println("方法2执行了");
    }
}
三、生成的字节码
Classfile /F:/jdk-learning/jvm/target/classes/com/learning/stack/dynamic_linking/DynamicLinkingTest.class
  Last modified 2023-10-28; size 756 bytes
  MD5 checksum 96b3029ecd8f2d56b0fc46825936f83b
  Compiled from "DynamicLinkingTest.java"
public class com.learning.stack.dynamic_linking.DynamicLinkingTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #9.#23         // java/lang/Object."<init>":()V
   #2 = Fieldref           #8.#24         // com/learning/stack/dynamic_linking/DynamicLinkingTest.num:I
   #3 = Fieldref           #25.#26        // java/lang/System.out:Ljava/io/PrintStream;
   #4 = String             #27            // 方法1执行了
   #5 = Methodref          #28.#29        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #6 = Methodref          #8.#30         // com/learning/stack/dynamic_linking/DynamicLinkingTest.methodTwo:()V
   #7 = String             #31            // 方法2执行了
   #8 = Class              #32            // com/learning/stack/dynamic_linking/DynamicLinkingTest
   #9 = Class              #33            // java/lang/Object
  #10 = Utf8               num
  #11 = Utf8               I
  #12 = Utf8               <init>
  #13 = Utf8               ()V
  #14 = Utf8               Code
  #15 = Utf8               LineNumberTable
  #16 = Utf8               LocalVariableTable
  #17 = Utf8               this
  #18 = Utf8               Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;
  #19 = Utf8               methodOne
  #20 = Utf8               methodTwo
  #21 = Utf8               SourceFile
  #22 = Utf8               DynamicLinkingTest.java
  #23 = NameAndType        #12:#13        // "<init>":()V
  #24 = NameAndType        #10:#11        // num:I
  #25 = Class              #34            // java/lang/System
  #26 = NameAndType        #35:#36        // out:Ljava/io/PrintStream;
  #27 = Utf8               方法1执行了
  #28 = Class              #37            // java/io/PrintStream
  #29 = NameAndType        #38:#39        // println:(Ljava/lang/String;)V
  #30 = NameAndType        #20:#13        // methodTwo:()V
  #31 = Utf8               方法2执行了
  #32 = Utf8               com/learning/stack/dynamic_linking/DynamicLinkingTest
  #33 = Utf8               java/lang/Object
  #34 = Utf8               java/lang/System
  #35 = Utf8               out
  #36 = Utf8               Ljava/io/PrintStream;
  #37 = Utf8               java/io/PrintStream
  #38 = Utf8               println
  #39 = Utf8               (Ljava/lang/String;)V
{
  int num;
    descriptor: I
    flags:

  public com.learning.stack.dynamic_linking.DynamicLinkingTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: bipush        10
         7: putfield      #2                  // Field num:I
        10: return
      LineNumberTable:
        line 7: 0
        line 8: 4
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      11     0  this   Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;

  public void methodOne();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #4                  // String 方法1执行了
         5: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: aload_0
         9: invokevirtual #6                  // Method methodTwo:()V
        12: aload_0
        13: dup
        14: getfield      #2                  // Field num:I
        17: iconst_1
        18: iadd
        19: putfield      #2                  // Field num:I
        22: return
      LineNumberTable:
        line 11: 0
        line 12: 8
        line 13: 12
        line 14: 22
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      23     0  this   Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;

  public void methodTwo();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #7                  // String 方法2执行了
         5: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 17: 0
        line 18: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  this   Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;
}
SourceFile: "DynamicLinkingTest.java"
四、字节码说明
4.1 常量池
Constant pool:
   #1 = Methodref          #9.#23         // java/lang/Object."<init>":()V
   #2 = Fieldref           #8.#24         // com/learning/stack/dynamic_linking/DynamicLinkingTest.num:I
   #3 = Fieldref           #25.#26        // java/lang/System.out:Ljava/io/PrintStream;
   #4 = String             #27            // 方法1执行了
   #5 = Methodref          #28.#29        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #6 = Methodref          #8.#30         // com/learning/stack/dynamic_linking/DynamicLinkingTest.methodTwo:()V
   #7 = String             #31            // 方法2执行了
   #8 = Class              #32            // com/learning/stack/dynamic_linking/DynamicLinkingTest
   #9 = Class              #33            // java/lang/Object
  #10 = Utf8               num
  #11 = Utf8               I
  #12 = Utf8               <init>
  #13 = Utf8               ()V
  #14 = Utf8               Code
  #15 = Utf8               LineNumberTable
  #16 = Utf8               LocalVariableTable
  #17 = Utf8               this
  #18 = Utf8               Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;
  #19 = Utf8               methodOne
  #20 = Utf8               methodTwo
  #21 = Utf8               SourceFile
  #22 = Utf8               DynamicLinkingTest.java
  #23 = NameAndType        #12:#13        // "<init>":()V
  #24 = NameAndType        #10:#11        // num:I
  #25 = Class              #34            // java/lang/System
  #26 = NameAndType        #35:#36        // out:Ljava/io/PrintStream;
  #27 = Utf8               方法1执行了
  #28 = Class              #37            // java/io/PrintStream
  #29 = NameAndType        #38:#39        // println:(Ljava/lang/String;)V
  #30 = NameAndType        #20:#13        // methodTwo:()V
  #31 = Utf8               方法2执行了
  #32 = Utf8               com/learning/stack/dynamic_linking/DynamicLinkingTest
  #33 = Utf8               java/lang/Object
  #34 = Utf8               java/lang/System
  #35 = Utf8               out
  #36 = Utf8               Ljava/io/PrintStream;
  #37 = Utf8               java/io/PrintStream
  #38 = Utf8               println
  #39 = Utf8               (Ljava/lang/String;)V
4.1 方法调用
  • 1.methodOne方法调用methodTwo方法

    9: invokevirtual #6 // Method methodTwo:()V

  • 2.invokevirtual调用虚方法

    1. #6表示Methodref方法引用,指向#8.#30

      #6 = Methodref #8.#30 // com/learning/stack/dynamic_linking/DynamicLinkingTest.methodTwo:()V

    1. #8表示Class

      #8 = Class #32 // com/learning/stack/dynamic_linking/DynamicLinkingTest

    1. #32表示类为com/learning/stack/dynamic_linking/DynamicLinkingTest

      #32 = Utf8 com/learning/stack/dynamic_linking/DynamicLinkingTest

    1. #30表示名字和返回类型

      #30 = NameAndType #20:#13 // methodTwo:()V

    1. #20表示名字为methodTwo

      #20 = Utf8 methodTwo

    1. #13表示返回类型为void

      #13 = Utf8 ()V

4.3 变量
    1. int num = 10;

    #2 = Fieldref #8.#24 // com/learning/stack/dynamic_linking/DynamicLinkingTest.num:I

    1. 属性引用,指向#8.#24
    1. #8表示Class

      #8 = Class #32 // com/learning/stack/dynamic_linking/DynamicLinkingTest

    1. #32表示类为com/learning/stack/dynamic_linking/DynamicLinkingTest

      #32 = Utf8 com/learning/stack/dynamic_linking/DynamicLinkingTest

    1. #24表示名字和类型

      #24 = NameAndType #10:#11 // num:I

    1. #10表示属性名字为num

      #10 = Utf8 num

    1. #11表示属性的类型int

      #11 = Utf8 I

4.4 字符串
    1. #4表示是字符串

      #4 = String #27 // 方法1执行了

    1. #27表示Utf8的字符串"方法1执行了"

      #27 = Utf8 方法1执行了

4.5 父类Object
    1. #1表示方法引用

      #1 = Methodref #9.#23 // java/lang/Object."<init>":()V

    1. #9表示类

      #9 = Class #33 // java/lang/Object

    1. #33表示类名为java/lang/Object

      #33 = Utf8 java/lang/Object

4.6 System类
    1. #3表示属性引用

      #3 = Fieldref #25.#26 // java/lang/System.out:Ljava/io/PrintStream;

    1. #25表示类

      #25 = Class #34 // java/lang/System

    1. #34表示类名为java/lang/System

      #34 = Utf8 java/lang/System

    1. #26表示名称和类型

      #26 = NameAndType #35:#36 // out:Ljava/io/PrintStream;

    1. #35表示名称为out

      #35 = Utf8 out

    1. #36表示类型为 Ljava/io/PrintStream

      #36 = Utf8 Ljava/io/PrintStream;

相关推荐
李长渊哦12 小时前
常用的 JVM 参数:配置与优化指南
java·jvm
数巨小码人15 小时前
QT SQL框架及QSqlDatabase类
jvm·sql·qt
martian6651 天前
【Java高级篇】——第16篇:高性能Java应用优化与调优
java·开发语言·jvm
李长渊哦1 天前
Java 虚拟机(JVM)方法区详解
java·开发语言·jvm
二十七剑2 天前
jvm中各个参数的理解
java·jvm
七禾页话2 天前
垃圾回收知识点
java·开发语言·jvm
小梁不秃捏2 天前
深入浅出Java虚拟机(JVM)核心原理
java·开发语言·jvm
xiaolingting3 天前
JVM层面的JAVA类和实例(Klass-OOP)
java·jvm·oop·klass·instanceklass·class对象
神仙别闹3 天前
基于Python+Sqlite实现的选课系统
jvm·python·sqlite
上分小子2.03 天前
jvm-Java虚拟机
java·开发语言·jvm