2016-05-15 201 views
4

我正在玩ASM并分析类的泛型签名。本节中的文件可能包含的内容描述here并且可以与下面的语法来概括:什么是::在签名中的含义?

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

FieldTypeSignature:ClassTypeSignature | [TypeSignature | TypeVar

ClassTypeSignature:11d中(/ Id)的 TypeArgs? *; *

TypeArgs(同上TypeArgs。):< TypeArg +>

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

TypeVar:T Id;

但是,我发现对于这不是真的一个案例:

trait SomeTrait 
class SomeClass[T <: SomeTrait] 

泛型签名SomeClass<T::LSomeTrait;>Ljava/lang/Object;

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

任何想法?

+1

http://stackoverflow.com/questions/20001427/double-colon-operator-in-java-8 – nullpointer

+0

@nullpointer如何可能的重复适用于此? – sepp2k

回答

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; 
... 
+0

不仅是一个很好的答案,我还了解到有一个':javap'命令:) – Mifeet

+0

太好了,谢谢! –