2010-10-02 4 views

Répondre

11

Vous l'obtenez comme vous l'avez montré. Assurez-vous de vous référer uniquement à elem dans le cadre de l'initialiseur de classe, pas dans d'autres méthodes où il devra être stocké afin qu'il puisse être rappelé.

Voici le bytecode pour ce que vous avez écrit (utilisation javap -p ClassName sur les classes compilées):

public Address(scala.xml.Elem); 
    Code: 
    0: aload_0 
    1: invokespecial #18; //Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: aload_1 
    6: ldC#19; //String attr1 
    8: invokevirtual #25; //Method scala/xml/Elem.$bslash:(Ljava/lang/String;)Lscala/xml/NodeSeq; 
    11: invokevirtual #30; //Method scala/xml/NodeSeq.text:()Ljava/lang/String; 
    14: putfield #11; //Field attr1:Ljava/lang/String; 
    17: return 

Notez qu'il n'y a qu'un seul putfield, à savoir celui d'initialiser le val attr1. Si elem ont été enregistrés dans la classe, il faudrait son propre putfield. Si vous modifiez le val à un def, vous obtenez à la place:

public Address(scala.xml.Elem); 
    Code: 
    0: aload_0 
    1: aload_1 
    2: putfield #12; //Field elem:Lscala/xml/Elem; 
    5: aload_0 
    6: invokespecial #31; //Method java/lang/Object."<init>":()V 
    9: return 

où vous pouvez voir que le Elem a été stocké de sorte que le def peut l'utiliser à chaque appel.

Si vous voulez le Elem à stocker et accessible, vous devez déclarer la classe

class Address(val elem: scala.xml.Elem) { ... } 

(notez le val). L'argument constructor est toujours stocké uniquement si vous utilisez une classe de cas: les classes de cas sont conçues pour la correspondance de modèle, et bien sûr vous devez stocker l'argument si vous tentez de vous y opposer plus tard.

Questions connexes