当前位置: 首页 > news >正文

JVM之Synthetic

Synthetic是人造,合成的意思,在虚拟机很多地方使用ACC_SYNTHETIC表示编译器自动生成的,区别于我们自己写的程序代码。这样说可能比较模糊,我们举个例子:我们创建一个内部类,如下

public class TestInnerClass {public void say(String msg) {System.out.println(msg);}class InnerClass {public void sayInner() {say("hello");}}
}

我们用javap看一下内部类InnerClass反编译之后的情况:

完整如下:

Classfile /F:/demo/mallsystem/provider/target/classes/com/mall/test/TestInnerClass$InnerClass.classLast modified 2024-11-28; size 638 bytesMD5 checksum 9f5efd7b8d0ad50545773d2a0e198f60Compiled from "TestInnerClass.java"
class com.mall.test.TestInnerClass$InnerClassminor version: 0major version: 52flags: ACC_SUPER
Constant pool:#1 = Fieldref           #5.#22         // com/mall/test/TestInnerClass$InnerClass.this$0:Lcom/mall/test/TestInnerClass;#2 = Methodref          #6.#23         // java/lang/Object."<init>":()V#3 = String             #24            // hello#4 = Methodref          #25.#26        // com/mall/test/TestInnerClass.say:(Ljava/lang/String;)V#5 = Class              #27            // com/mall/test/TestInnerClass$InnerClass#6 = Class              #28            // java/lang/Object#7 = Utf8               this$0#8 = Utf8               Lcom/mall/test/TestInnerClass;#9 = Utf8               <init>#10 = Utf8               (Lcom/mall/test/TestInnerClass;)V#11 = Utf8               Code#12 = Utf8               LineNumberTable#13 = Utf8               LocalVariableTable#14 = Utf8               this#15 = Utf8               InnerClass#16 = Utf8               InnerClasses#17 = Utf8               Lcom/mall/test/TestInnerClass$InnerClass;#18 = Utf8               sayInner#19 = Utf8               ()V#20 = Utf8               SourceFile#21 = Utf8               TestInnerClass.java#22 = NameAndType        #7:#8          // this$0:Lcom/mall/test/TestInnerClass;#23 = NameAndType        #9:#19         // "<init>":()V#24 = Utf8               hello#25 = Class              #29            // com/mall/test/TestInnerClass#26 = NameAndType        #30:#31        // say:(Ljava/lang/String;)V#27 = Utf8               com/mall/test/TestInnerClass$InnerClass#28 = Utf8               java/lang/Object#29 = Utf8               com/mall/test/TestInnerClass#30 = Utf8               say#31 = Utf8               (Ljava/lang/String;)V
{final com.mall.test.TestInnerClass this$0;descriptor: Lcom/mall/test/TestInnerClass;flags: ACC_FINAL, ACC_SYNTHETICcom.mall.test.TestInnerClass$InnerClass(com.mall.test.TestInnerClass);descriptor: (Lcom/mall/test/TestInnerClass;)Vflags:Code:stack=2, locals=2, args_size=20: aload_01: aload_12: putfield      #1                  // Field this$0:Lcom/mall/test/TestInnerClass;5: aload_06: invokespecial #2                  // Method java/lang/Object."<init>":()V9: returnLineNumberTable:line 12: 0LocalVariableTable:Start  Length  Slot  Name   Signature0      10     0  this   Lcom/mall/test/TestInnerClass$InnerClass;0      10     1 this$0   Lcom/mall/test/TestInnerClass;public void sayInner();descriptor: ()Vflags: ACC_PUBLICCode:stack=2, locals=1, args_size=10: aload_01: getfield      #1                  // Field this$0:Lcom/mall/test/TestInnerClass;4: ldc           #3                  // String hello6: invokevirtual #4                  // Method com/mall/test/TestInnerClass.say:(Ljava/lang/String;)V9: returnLineNumberTable:line 14: 0line 15: 9LocalVariableTable:Start  Length  Slot  Name   Signature0      10     0  this   Lcom/mall/test/TestInnerClass$InnerClass;
}
SourceFile: "TestInnerClass.java"
InnerClasses:#15= #5 of #25; //InnerClass=class com/mall/test/TestInnerClass$InnerClass of class com/mall/test/TestInnerClass

重点看下面标记的,ACC_SYNTHETIC标记出现了

这里编译器在内部类生成了一个TestInnerClass的引用对象this$0,因为是编译器自动合成的,所以标记了ACC_SYNTHETIC。

而下面是内部类的构造方法,可以看到它传入了外部类的实例对象,之后把它赋值给this$0

aload_0默认是实例方法第一个参数是this,即内部类自己的引用

aload_1则是加载第一个入参也就是外部类实例对象

putfield #1就是把外部实例设置给this$0

所以这也就解释了为什么内部类创建需要外部类对象创建了,如果外部类对象还没有生成,怎么传给内部类的构造方法呢?

而我们内部类能调用外部类的方法,也正是通过外部类的实例对象调用的

http://www.lryc.cn/news/495693.html

相关文章:

  • HCIE IGP双栈综合实验
  • 【k8s】监控metrics-server
  • 第六届国际科技创新学术交流会暨管理科学信息化与经济创新发展(MSIEID 2024)
  • 将面具贴到人脸上的过程
  • 【Maven】Nexus私服
  • AI高中数学教学视频生成技术:利用通义千问、MathGPT、视频多模态大模型,语音大模型,将4个模型融合 ,生成高中数学教学视频,并给出实施方案。
  • 探索温度计的数字化设计:一个可视化温度数据的Web图表案例
  • windows电脑上安装树莓派操作系统
  • 交换机四大镜像(端口镜像、流镜像、VLAN镜像、MAC镜像)应用场景、配置实例及区别对比
  • 我不是挂王-用python实现燕双鹰小游戏
  • Java:反射、注解
  • Java 通过枚举类减少if else
  • 单链表---移除链表元素
  • 认识redis 及 Ubuntu安装redis
  • Java开发网络安全常见问题
  • C#基础之委托,事件
  • nginx配置静态资源的访问
  • JS的魔法三角:constructor、prototype与__proto__
  • CA系统(file.h---申请认证的处理)
  • matlab显示sin二维图
  • 验证 kubelet 服务已经停止并且不再生成错误日志
  • 【Linux】进程控制-----进程替换
  • 安装SQL Server 2022提示需要Microsoft .NET Framework 4.7.2 或更高版本
  • 使用ECharts创建带百分比标注的环形图
  • 学习threejs,设置envMap环境贴图创建反光效果
  • go语言里的mkdir mkdirall有什么区别?
  • 使用Python OpenCV实现图像形状检测
  • 继上一篇,设置弹框次数以及自适应图片弹框,部分机型(vivo)老手机不显示的问题
  • 基于RISC-V 的代理内核实验(使用ub虚拟机安装基本环境)
  • 【MMKV】HarmonyOS中的优秀轻量化存储方式