Вы достигаете этого так, как вы показали.Просто убедитесь, что вы ссылаетесь только на elem
как часть инициализатора класса, а не в других методах, где он должен храниться, чтобы его можно было вызвать.1004 * для скомпилированных классов):
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
Обратите внимание, что существует только один putfield
, а именно тот, который инициализирует val attr1
.Если бы elem
были сохранены внутри класса, ему потребовался бы собственный putfield
.Если вы измените val
на def
, вместо этого вы получите:
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
, где вы увидите, что Elem
был сохранен, поэтому def
может использовать его при каждом вызове.
Если вы хотите, чтобы Elem
были сохранены и доступны, вам нужно объявить класс
class Address(val elem: scala.xml.Elem) { ... }
(обратите внимание на val
).
Только если вы используете класс case, аргумент конструктора всегда сохраняется: классы case предназначены для сопоставления с образцом, и, конечно, вам нужно сохранить аргумент, если вы позже попытаетесь сопоставить его.