包 java.lang.constant
invokedynamic
调用站点)的类和接口。这些类适用于字节码读取和写入 API、invokedynamic
引导程序、字节码内部 API 以及编译时或链接时程序分析工具。
每个读取和写入字节码指令的 API 都需要将操作数建模为这些指令和其他类文件结构(例如引导方法表或堆栈map中的条目,它们经常引用类文件常量池中的条目。)此类条目可以表示值基本类型,例如字符串或整数;程序的一部分,例如类或方法句柄;或任意用户定义类型的值。 ConstantDesc
层次结构以名义形式提供常量池条目的表示,便于 API 对字节码指令的操作数进行建模。
标称描述符
ConstantDesc
是对常量值的描述。这样的描述就是常量值的nominal form;它不是值本身,而是用于描述值、将值存储在常量池条目中或在给定类加载上下文的情况下重构值的“配方”。每个 ConstantDesc
都知道如何通过 ConstantDesc.resolveConstantDesc
resolve 自身——计算它描述的值。这允许接受 ConstantDesc
对象的 API 以反射方式评估它们,前提是它们的标称描述中引用的类和方法存在且可访问。
ConstantDesc
的子类型描述了各种常数值。对于 JVMS 4.4 中定义的每种类型的可加载常量池条目,都有一个对应的 ConstantDesc
子类型:ClassDesc
、MethodTypeDesc
、DirectMethodHandleDesc
、String
、Integer
、Long
、Float
、Double
和 DynamicConstantDesc
。这些类提供特定于类型的访问器方法来提取该常量的标称信息。当字节码编写 API 遇到 ConstantDesc
时,它应该检查它以查看它是这些类型中的哪一种,对其进行转换,提取其标称信息,并在常量池中生成相应的条目。当字节码读取 API 遇到常量池条目时,它可以将其转换为适当类型的标称描述符。对于动态常量,字节码读取 API 可能希望使用工厂 DynamicConstantDesc.ofCanonical
,它将检查引导程序,并且对于众所周知的引导程序,返回 DynamicConstantDesc
的更具体的子类型,例如 Enum.EnumDesc
。
另一种获取值的名义描述的方法是询问值本身。 Constable
是一种类型,其值可以以标称形式将自身描述为 ConstantDesc
。 String
和 Class
等基本类型实现 Constable
,用户定义的类也可以。生成类文件的实体(例如编译器)可以对 constable 对象进行内省,以获得一种更有效的方式来表示它们在类文件中的值。
这个包还包括 DynamicCallSiteDesc
,它代表一个(不可加载的) Constant_InvokeDynamic_info
常量池条目。它描述了与 invokedynamic
指令关联的引导方法、调用名称和类型以及引导参数。也适用于描述字节码读写API中的invokedynamic
调用点。
- 看Java 虚拟机规范:
-
4.4 常量池
- 自从:
- 12
-
类描述表示类型 constable 。名义描述符 的预定义值用于公共常量,包括原始类类型和其他公共平台类型的描述符,以及标准引导方法的方法句柄的描述符。直接
MethodHandle
的 名义描述符。可以用 DirectMethodHandleDesc 描述的方法句柄的种类。名义描述符 用于invokedynamic
呼叫站点。一个 名义描述符 用于动态常量(一个在常量池中用Constant_Dynamic_info
描述的。)名义描述符 代表MethodHandle
常量。名义描述符 代表 MethodType 常量。