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.