目录 一、说明 二、代码示例 三、生成的字节码 四、字节码说明 4.1 常量池 4.1 方法调用 4.3 变量 4.4 字符串 4.5 父类Object 4.6 System类
一、说明
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.classLast modified 2023-10-28; size 756 bytesMD5 checksum 96b3029ecd8f2d56b0fc46825936f83bCompiled from "DynamicLinkingTest.java"
public class com.learning.stack.dynamic_linking.DynamicLinkingTestminor version: 0major version: 52flags: 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: Iflags:public com.learning.stack.dynamic_linking.DynamicLinkingTest();descriptor: ()Vflags: ACC_PUBLICCode:stack=2, locals=1, args_size=10: aload_01: invokespecial #1 // Method java/lang/Object."<init>":()V4: aload_05: bipush 107: putfield #2 // Field num:I10: returnLineNumberTable:line 7: 0line 8: 4LocalVariableTable:Start Length Slot Name Signature0 11 0 this Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;public void methodOne();descriptor: ()Vflags: ACC_PUBLICCode:stack=3, locals=1, args_size=10: 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;)V8: aload_09: invokevirtual #6 // Method methodTwo:()V12: aload_013: dup14: getfield #2 // Field num:I17: iconst_118: iadd19: putfield #2 // Field num:I22: returnLineNumberTable:line 11: 0line 12: 8line 13: 12line 14: 22LocalVariableTable:Start Length Slot Name Signature0 23 0 this Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;public void methodTwo();descriptor: ()Vflags: ACC_PUBLICCode:stack=2, locals=1, args_size=10: 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;)V8: returnLineNumberTable:line 17: 0line 18: 8LocalVariableTable:Start Length Slot Name Signature0 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
#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
#30 = NameAndType #20:#13 // methodTwo:()V
#20 = Utf8 methodTwo
#13 = Utf8 ()V
4.3 变量
#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
#24 = NameAndType #10:#11 // num:I
#10 = Utf8 num
#11 = Utf8 I
4.4 字符串
#4 = String #27 // 方法1执行了
#27 = Utf8 方法1执行了
4.5 父类Object
#1 = Methodref #9.#23 // java/lang/Object."<init>":()V
#9 = Class #33 // java/lang/Object
3. #33表示类名为java/lang/Object
#33 = Utf8 java/lang/Object
4.6 System类
#3 = Fieldref #25.#26 // java/lang/System.out:Ljava/io/PrintStream;
#25 = Class #34 // java/lang/System
3. #34表示类名为java/lang/System
#34 = Utf8 java/lang/System
#26 = NameAndType #35:#36 // out:Ljava/io/PrintStream;
#35 = Utf8 out
6. #36表示类型为 Ljava/io/PrintStream
#36 = Utf8 Ljava/io/PrintStream;