什么::在类签名中意味着什么?

时间:2016-05-15 14:28:51

标签: scala

我目前正在玩ASM并分析类的泛型签名。本节中记录的可能内容描述为here,可以使用以下语法进行总结:

TypeSignature: Z | C | B | S |我| F | J | D | FieldTypeSignature

FieldTypeSignature: ClassTypeSignature | [TypeSignature | TypeVar

ClassTypeSignature: L Id(/ Id) TypeArgs? (.Id TypeArgs?)*; *

TypeArgs: < TypeArg +>

TypeArg: ** | (+ | - )? FieldTypeSignature *

TypeVar: T Id;

然而,我发现一个案例并非如此:

trait SomeTrait
class SomeClass[T <: SomeTrait]

SomeClass的通用签名:<T::LSomeTrait;>Ljava/lang/Object;

我不明白为什么::出现在这里,这是什么意思。从语法的角度来看,Doubled :无效。有趣的是,如果我将trait替换为abstract class,则::将被替换为单个:(预期的内容)。

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

类文件规范说明(在4.7.9.1. Signatures部分中):

ReferenceTypeSignature:
  ClassTypeSignature
  TypeVariableSignature
  ArrayTypeSignature
TypeParameters:
  < TypeParameter {TypeParameter} >
TypeParameter:
  Identifier ClassBound {InterfaceBound}
ClassBound:
  : [ReferenceTypeSignature]
InterfaceBound:
  : ReferenceTypeSignature

将此应用于<T::LSomeTrait;>表示:

   TypeParameters
=> < TypeParameter {TypeParameter} >
=> < Identifier ClassBound {InterfaceBound} {TypeParameter} >
=> < T ClassBound {InterfaceBound} {TypeParameter} >
=> < T : [ReferenceTypeSignature] {InterfaceBound} {TypeParameter} >
=> < T : {InterfaceBound} {TypeParameter} >
=> < T : : ReferenceTypeSignature {TypeParameter} >
=> < T : : LSomeTrait; {TypeParameter} >
=> < T : : LSomeTrait; >
=> <T::LSomeTrait;>

总而言之,第一个冒号引入了类绑定,第二个冒号引入了接口绑定。两个冒号保持在一起这一事实意味着没有阶级约束。

使用类和接口签名:

scala> trait T
defined trait T

scala> abstract class A
defined class A

scala> class C[X <: A with T]
defined class C

scala> :javap C
  Size 554 bytes
  MD5 checksum 6273d85df5987e350e7112726756a55f
  Compiled from "<console>"
public class C<X extends A & T> extends java.lang.Object
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Utf8               C
   #2 = Class              #1             // C
   #3 = Utf8               <X:LA;:LT;>Ljava/lang/Object;
...