2016-05-15 12 views
4

Ich spiele gerade mit ASM und analysiere die Generikasignaturen der Klassen. Der dokumentierte mögliche Inhalt in diesem Abschnitt wird here beschrieben und könnte mit der folgenden Grammatik zusammenfassen:Was bedeutet :: in der Klassensignatur?

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

FieldTypeSignature:ClassTypeSignature | [TypSignatur | TypeVar

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

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

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

TypVar:T Id;

Allerdings fand ich für einen Fall, dass es nicht wahr ist:

trait SomeTrait 
class SomeClass[T <: SomeTrait] 

Generics Signatur für SomeClass: <T::LSomeTrait;>Ljava/lang/Object;

Ich verstehe nicht, warum :: hier erschienen und was bedeutet es. Doubled : ist nicht von der Grammatik Sicht gültig. Was interessant ist, wenn ich trait durch abstract class ersetze, wird die :: durch eine einzige ersetzt werden : (was erwartet wird).

Irgendwelche Ideen?

+1

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

+0

@nullpointer Wie funktioniert das gilt hier? – sepp2k

Antwort

3

Die Klassendatei Spezifikation sagt (in Abschnitt 4.7.9.1. Signatures):

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

Angewandt auf <T::LSomeTrait;> bedeutet:

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;> 

Alles in allem ist der erste Doppelpunkt die Klasse einführt gebunden und den zweiten Doppelpunkt führt die Schnittstelle gebunden ein. Die Tatsache, dass die zwei Doppelpunkte zusammenbleiben, bedeutet, dass es keine Klassenbindung gibt.

Signatur sowohl mit einer Klasse und einer Schnittstelle:

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

Nicht nur eine gute Antwort, ich habe auch gelernt, es gibt einen ': javap' Befehl :) – Mifeet

+0

Großartig, danke! –