JVM规范:通用签名的语法需要提前查看

  • 本文关键字:语法 规范 JVM jvm .class-file
  • 更新时间 :
  • 英文 :


在通用签名的规范中,ClassSignature的形式如下

ClassSignature:
[TypeParameters] SuperclassSignature {SuperinterfaceSignature}
TypeParameters:
< TypeParameter {TypeParameter} >
TypeParameter:
Identifier ClassBound {InterfaceBound}
ClassBound:
: [ReferenceTypeSignature]
InterfaceBound:
: ReferenceTypeSignature

因此,可以省略类型参数的超类边界(此处的一些示例)。

如果我有一个类声明public class A<T, LFooBar>,Java编译器会生成签名<T:Ljava/lang/Object;LFooBar:Ljava/lang/Object;>Ljava/lang/Object;

IUC,可以省略类绑定,在这种情况下,签名将被<T:LFooBar:>Ljava/lang/Object;

解析该短签名需要向前看第二个:,以便知道T:LFooBar:是两个类型参数,而不是一个类型参数T类绑定FooBar

也许在实践中,只有在有接口绑定的情况下才能删除类绑定?对于public class A<T extends Comparable<? super T>>,javac 生成签名<T::Ljava/lang/Comparable<-TT;>;>Ljava/lang/Object;。但我想我不能依赖这个假设。

我是不是误会了什么?

如果你仔细观察,唯一可以遵循省略ReferenceTypeSignature的是Identifier>。由于ReferenceTypeSignature必须以[开头或以;结尾,并且标识符不能包含这些字符,而标识符后必须跟有:,不能显示为类型签名,因此这些选项之间没有歧义。

请注意,标识符可以以>开头,因此您需要提前寻找冒号以确定您是否在末尾TypeParameters。但这是一个单独的问题。

我不确定 JVM 是如何实现它的,但一种可能的方法是:

  • 检查第一个字符。如果是 [,则具有类型签名。如果>,请提前扫描第一个 [、; 或 :。如果您看到的第一个是 :,则表示您具有标识符,否则您具有类型结束参数。
  • 否则,请提前扫描第一个 ;或 :。如果是 :,则您有一个标识符,否则您有一个类绑定。

编辑:签名中的标识符不能包含>,因此请忽略该位。(它们也不能包含:,这是另一个潜在的歧义来源)

最新更新