一、说明
- 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调用虚方法
- 3. #6表示Methodref方法引用,指向#8.#30
#6 = Methodref #8.#30 // com/learning/stack/dynamic_linking/DynamicLinkingTest.methodTwo:()V
- 4. #8表示Class
#8 = Class #32 // com/learning/stack/dynamic_linking/DynamicLinkingTest
- 5. #32表示类为com/learning/stack/dynamic_linking/DynamicLinkingTest
#32 = Utf8 com/learning/stack/dynamic_linking/DynamicLinkingTest
- 6. #30表示名字和返回类型
#30 = NameAndType #20:#13 // methodTwo:()V
- 7. #20表示名字为methodTwo
#20 = Utf8 methodTwo
- 8. #13表示返回类型为void
#13 = Utf8 ()V
4.3 变量
- 1. int num = 10;
#2 = Fieldref #8.#24 // com/learning/stack/dynamic_linking/DynamicLinkingTest.num:I
- 2. 属性引用,指向#8.#24
- 3. #8表示Class
#8 = Class #32 // com/learning/stack/dynamic_linking/DynamicLinkingTest
- 4. #32表示类为com/learning/stack/dynamic_linking/DynamicLinkingTest
#32 = Utf8 com/learning/stack/dynamic_linking/DynamicLinkingTest
- 5. #24表示名字和类型
#24 = NameAndType #10:#11 // num:I
- 6. #10表示属性名字为num
#10 = Utf8 num
- 7. #11表示属性的类型int
#11 = Utf8 I
4.4 字符串
- 1. #4表示是字符串
#4 = String #27 // 方法1执行了
- 2. #27表示Utf8的字符串"方法1执行了"
#27 = Utf8 方法1执行了
4.5 父类Object
- 1. #1表示方法引用
#1 = Methodref #9.#23 // java/lang/Object."<init>":()V
- 2. #9表示类
#9 = Class #33 // java/lang/Object
- 3. #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;
- 2. #25表示类
#25 = Class #34 // java/lang/System
- 3. #34表示类名为java/lang/System
#34 = Utf8 java/lang/System
- 4. #26表示名称和类型
#26 = NameAndType #35:#36 // out:Ljava/io/PrintStream;
- 5. #35表示名称为out
#35 = Utf8 out
- 6. #36表示类型为 Ljava/io/PrintStream
#36 = Utf8 Ljava/io/PrintStream;
文章来源地址https://www.toymoban.com/news/detail-716321.html
文章来源:https://www.toymoban.com/news/detail-716321.html
到了这里,关于【jvm】虚拟机栈之动态链接的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!