加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala中的对象初始化序列在固有层次结构中

发布时间:2020-12-16 08:47:54 所属栏目:安全 来源:网络整理
导读:我是 java的scala的新手,并且在固有的层次结构中被scala的对象初始化序列搞糊涂了. IIRC,在 Java中,如果初始化了子类的对象,则在其自己的构造函数的任何代码之前调用其基类的构造函数.在scala中,我的行为完全不同.请考虑以下示例: class Point(val x: Int,v
我是 java的scala的新手,并且在固有的层次结构中被scala的对象初始化序列搞糊涂了. IIRC,在 Java中,如果初始化了子类的对象,则在其自己的构造函数的任何代码之前调用其基类的构造函数.在scala中,我的行为完全不同.请考虑以下示例:

class Point(val x: Int,val y: Int){
    val name = this.makeName;

    def makeName: String = {
        println("makeName at super.");

        "[" + x + "," + y + "]";
    }

    override def toString: String = name;
}

class ColorPoint(override val x: Int,override val y: Int,var color: String) extends Point(x,y) {

    // key statement
    println(name);

    override def makeName: String = {
        println("makeName at sub.");

        super.makeName + ":" + myColor;
    }

    val myColor = color;

    override def toString: String = name;
}

我们只考虑使用javap转储的ColorPoint构造函数的字节代码.如果代码包含关键语句println(name);字节码是

public ColorPoint(int,int,java.lang.String);
  Code:
   0:   aload_0
   1:   aload_3
   2:   putfield        #13; //Field color:Ljava/lang/String;
   5:   aload_0
   6:   iload_1
   7:   iload_2
   8:   invokespecial   #18; //Method Point."<init>":(II)V
   11:  getstatic       #24; //Field scala/Predef$.MODULE$:Lscala/Predef$;
   14:  aload_0
   15:  invokevirtual   #28; //Method name:()Ljava/lang/String;
   18:  invokevirtual   #32; //Method scala/Predef$.println:(Ljava/lang/Object;)V
   21:  aload_0
   22:  aload_3
   23:  putfield        #34; //Field myColor:Ljava/lang/String;
   26:  return

我们可以看到字段myColor在invokespecial之后初始化,即在初始化基类之后.

如果我注释掉语句println(name);字节代码是:

public ColorPoint(int,java.lang.String);
  Code:
   0:   aload_0
   1:   aload_3
   2:   putfield        #13; //Field color:Ljava/lang/String;
   5:   aload_0
   6:   aload_3
   7:   putfield        #15; //Field myColor:Ljava/lang/String;
   10:  aload_0
   11:  iload_1
   12:  iload_2
   13:  invokespecial   #20; //Method Point."<init>":(II)V
   16:  return

我们看到myColor字段在invokespecial之前初始化,即在base初始化之前.

那是什么原因?任何文件/文章都指明了这种行为?

顺便说一句,我的scala版本是2.7.7final(OpenJDK Server VM,Java 1.6.0_20).谢谢,最诚挚的问候!

解决方法

编译器只是按顺序执行.这里有一些文档.

https://github.com/paulp/scala-faq/wiki/Initialization-Order

其主要部分如下.

  1. Superclasses are fully initialized before subclasses.
  2. Otherwise,in declaration order.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读