2016-05-15 4 views
4

В настоящее время я играю с ASM и анализирую подписи генераторов. Документально возможное содержание в данном разделе описывается here и можно резюмировать с помощью следующей грамматике:Что означает :: означает подпись класса?

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

FieldTypeSignature:ClassTypeSignature | [TypeSignature | TypeVar

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

TypeArgs (Id TypeArgs.?):< TypeArg +>

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

ТипVar: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

Отлично, спасибо! –

Смежные вопросы