在通用签名规范中,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;
。但我想我不能依赖这个假设。
我误解了什么吗?
答案 0 :(得分:0)
如果仔细观察,唯一可以遵循省略ReferenceTypeSignature
的内容是Identifier
或>
。由于ReferenceTypeSignature
必须以[
开头或以;
结尾,且标识符不能包含这些字符,而标识符后面必须跟:
,后者可以' t出现类型签名,这些选项之间没有歧义。
请注意,标识符可以以>
开头,因此您需要提前查看冒号,以确定您是否在TypeParameters
末尾。但这是一个单独的问题。
我不确定JVM是如何实现它的,但一种可能的方法是:
编辑:签名中的标识符不能包含>
,因此请忽略该位。 (它们也不能包含:
,另一个潜在的歧义来源)