2010-10-02 38 views

回答

11

您可以按照您所展示的方式实现它。只要确保只将elem作为类初始化程序的一部分,而不是其他方法,因为它必须存储以便可以调用。

这里的字节码为你写的(在编译的类使用javap -p ClassName):

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。如果你改变了valdef,你会得到相反:

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类是为模式匹配而设计的,当然,如果您稍后尝试与之匹配,则需要存储参数。