2017-04-17 15 views
2

I definiert Merkmal in Scala alsMit Val in Scala Trait

trait checkTrait 
{ 
    val name:String = "male" 
} 

Wie ich verstehen, wenn val in Scala Klasse deklariert sind nur Accessoren erzeugt werden, aber wenn ich über Code mit JAD Decompiler dekompiliert wird erzeugt folgende

public interface checkTrait 
{ 

    public abstract void checkTrait$_setter_$name_$eq(String s); 
    public abstract String name(); 
} 

Nicht in der Lage zu verstehen, was genau ist "checkTrait $ Setter $ name_ $ eq (String s)" ist es Mutator? Wenn es Mutator ist, dann wie sie generiert werden, weil laut Sprachspezifikation Mutatoren für Vals nicht generiert werden

Antwort

2

Ja, Sie haben Recht. checkTrait$setter$name_$eq(String s) ist eine Mutator Methode für das Setzen des Wertes name.

Dies wird verursacht von Scala Charakterzug und seit Javainterface Felder sind implicitly static and final, aber in Scalatrait Feld Java-Schnittstelle umwandeln muß ein Feld von class oder instance sein. so Mutator Methode wird verwendet, um das Feld für checkTrait 's Unterklasse zu initiieren.

Java 8 (pre-release) interface member variables

Voll Erläuterung:

Als Ihr Dekompilierungsprozeß, Scala Compilertrait konvertieren checkTrait zu Java ‚s interface. und für diese Dekompilierungsprozeß sollte eine andere statischeinit Methode in checkTrait haben, wie:

public interface checkTrait { 
    public abstract void checkTrait$_setter_$name_$eq(java.lang.String); 

    public abstract java.lang.String name(); 

    public static void $init$(checkTrait); 
    Code: 

     1: ldc   #18     // String male 
     3: invokeinterface #20, 2   // InterfaceMethod checkTrait$_setter_$name_$eq:(Ljava/lang/String;)V 
     8: return 
} 

Wie Sie sehen können, ist dies ein statische init Methode mit einer checkTrait Instanz Parameter zu akzeptieren. und rufen checkTrait$_setter_$name_$eq dieses Mutator-Methode initial Wert mit Wert: männlich.

Lassen Sie uns zu extendcheckTrait versuchen:

class A extends checkTrait 

und decompile diese A Klasse:

public class A implements checkTrait { 
    public java.lang.String name(); 
    Code: 
     0: aload_0 
     1: getfield  #15     // Field name:Ljava/lang/String; 
     4: areturn 

    public void checkTrait$_setter_$name_$eq(java.lang.String); 
    Code: 
     0: aload_0 
     1: aload_1 
     2: putfield  #15     // Field name:Ljava/lang/String; 
     5: return 

    public A(); 
    Code: 
     0: aload_0 
     1: invokespecial #24     // Method java/lang/Object."<init>":()V 
     4: aload_0 
     5: invokestatic #28     // InterfaceMethod checkTrait.$init$:(LcheckTrait;)V 
     8: return 
} 

Und wir können finden, in der A ‚s Konstruktor wird aufrufen es die checkTraitstatic init methode von:

5: invokestatic #28     // InterfaceMethod checkTrait.$init$:(LcheckTrait;)V 

mit Pass-Strom Instanz zu init name Feldwert.

Also das ist Scala Art der Umsetzung eines Feldes in Merkmal.