JVM规范:通用签名的语法需要前瞻性

时间:2017-05-31 12:32:42

标签: jvm .class-file

在通用签名规范中,ClassSignature的格式为

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

因此可以省略类型参数的超类绑定(一些examples here)。

如果我有一个类声明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;。但我想我不能依赖这个假设。

我误解了什么吗?

1 个答案:

答案 0 :(得分:0)

如果仔细观察,唯一可以遵循省略ReferenceTypeSignature的内容是Identifier>。由于ReferenceTypeSignature必须以[开头或以;结尾,且标识符不能包含这些字符,而标识符后面必须跟:,后者可以' t出现类型签名,这些选项之间没有歧义。

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

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

  • 检查第一个字符。如果是[,你有一个类型签名。如果是>,则提前扫描第一个[,;或:。如果你看到的第一个是:,那意味着你有标识符,否则你有类型参数的结尾。
  • 否则,请先扫描第一个;要么 :。如果是:,则您有一个标识符,否则您有一个类绑定。

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