scala - 在不使构造函数参数成为对象成员的情况下创建对象

时间:2010-10-02 07:38:01

标签: class scala object

我有

class Address(elem: scala.xml.Elem){
    val attr1 = (elem \ "attr1") text
    ...
}

我不希望elem成为Address的成员,以便在内存中创建数百万个此类对象时将脚印保持为最小。什么是scala方法来实现这一目标? 感谢。

1 个答案:

答案 0 :(得分: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的{​​{1}}。如果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类是为模式匹配而设计的,当然,如果您稍后尝试匹配它,则需要存储参数。