`
zhouchaofei2010
  • 浏览: 1104476 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

scala 构造顺序与java 的构造顺序的区别

阅读更多
有如下scala代码 
ConstructionOrder.scala
package quickanswer.chapter8

class Creature {
  val range: Int = 10
  val env: Array[Int] = new Array[Int](this.range)///calls the range() 方法而不是对字段的的直接引用  和java 的区别
}

class Ant extends Creature {
  override val range = 2
}

object ConstructionOrder extends App {
  val ant= new Ant
   println(ant.range);
  println(ant.env.length);

}
 
执行结果是
2
0
 
有如下java 代码 ConstructionOrder.scala
CreatureJava.java
package quickanswer.chapter8;

class CreatureJava {
     int range=10;
     int[] env = new int[range];

     public int getRange() {
        return range;
    }

}
class AntJava extends CreatureJava {

     int  range = 2;

    @Override
    public int getRange() {
        return range ;
    }

}
public class ConstructionOrderJava {

    public static void main(String[] args) {
        AntJava a=new AntJava();
        System.out.println(a.range);
        System.out.println(a.env.length);

    }

}
 
执行结果是
2
10
 
太奇怪了,scala 输出的结果和java 的输出结果竟然不一样
为什么会这样?
 
通过反编译Creature.class(scala编译生成的) 文件 ,得到如下代码
 
public class Creature
{
  public int range()
  {
    return this.range;
  }

  private final int range = 10;

  public int[] env()
  {
    return this.env;
  }

  private final int[] env = new int[range()];
}
 
发现:private final int[] env = new int[range()];
原来scala 中,就算是代码中宿主类中对  range的字段的访问是直接访问的,但是是通过scala编译后却是通过方法range()  (相同于java中的getter)来访问的。
 
所以在如上对Ant类 生成对象的构造过程如下:
 

1. The Ant constructor calls the Creature constructor before doing its own construction.

2. The Creature constructor sets its range field to 10.

3. The Creature constructor, in order to initialize the env array, calls the range() getter.

4. That method is overridden to yield the (as yet uninitialized) range field of the Ant class.

5. The range method returns 0. (That is the initial value of all integer fields when an object is allocated.)

6. env is set to an array of length 0.

7. The Ant constructor continues, setting its range field to 2.

 
 
 
补充:
1、如上内容是对 《快学scala》8.10 构造顺序和提前定义  这一节的疑惑的测试与探究
 
 
2、对变量的访问,scala 和java 是不同的,通过javap发现,scala 是方法 invokemethod
,而java 是getField 
 

 

3、这里的教训是构造器内部不应该依赖val值。 可以用var 值来替换。因为scala在语法上子类不可以重载父类的var变量,如果子类重写了父类的var值, 编译就不能通过
 
4、对var类型的 range2 值的访问,scala 编译后也是通过方法range2 ()的访问的,但是scala 语法上限制了var 不能重写,所以父类的构造器初始化可以依赖var值
0
0
分享到:
评论

相关推荐

    Scala基础与实践

    特质的构造顺序是从左到右。 6. apply方法:Scala中的apply方法使得实例化一个对象变得更加简洁。当一个单例对象(object)有一个apply方法时,可以使用类名直接创建实例,而不需要显式调用new关键字。 7. 包:...

    Scala 编程中文版-前13章

    - **Scala**:一种多范式的编程语言,融合了面向对象编程和函数式编程的特点,设计初衷是为了改进Java语言的一些局限性。 - **创始人**:Martin Odersky教授,他是Scala语言的设计者和创造者,同时也在瑞士洛桑联邦...

    快学Scala-课后习题答案-源码

    1. **基础语法**: Scala的基础语法与Java相似,但更加简洁。了解变量声明、数据类型(包括基本类型和引用类型)、控制流结构(如if-else、for循环、while循环)以及函数定义等是入门的第一步。 2. **面向对象编程**...

    快学 scala 中文版 带完整目录

    8.10 构造顺序和提前定义 L3 110 8.11 Scala类继承关系 112 8.12 对象相等性 L1 114 8.13 值类 L2 116 练习 117 第9章 文件和正则表达式 A1 121 9.1 读取行 121 9.2 读取字符 122 9.3 读取词法单元和数字 ...

    scala从入门到精通技术教学视频

    02.Scala程序和Java程序对比 03.Scala环境搭建 04.Scala解释器 05.案例_做最好的自己 第二章 变量和数据类型 00.导学 01.输出语句和分号 02.Scala中的常量 03.Scala中的变量 04.字符串的定义 05.惰性赋值 06.标识符 ...

    Scala编程实战.rar

    14. **文件和进程**:Scala提供了与文件系统交互的API,可以读写文件、创建目录,甚至启动和管理子进程。这对于实现涉及I/O操作的任务非常有用。 15. **Actors和并发**:Scala的Actor模型是一种并发编程模型,每个...

    英文版ScalaReference.pdf

    Scala编译器为了兼容Java虚拟机,会擦除所有泛型信息,保留类型的基本结构。 #### 四、声明与定义 **4.1 值声明与定义** 用于定义不可变值。 **4.2 变量声明与定义** 用于定义可变变量。 **4.3 类型声明与类型...

    java函数

    虽然Java标准版不直接支持尾递归优化,但JVM和某些编译器(如Scala的编译器)可能提供这种优化,以避免无限递归导致的栈溢出。 14. **内联函数(Inlined Functions)**: 虽然Java不直接支持内联函数,但JIT...

    基础篇.pdf

    构造函数用于创建对象,Java有默认构造器,也可以自定义构造器。变量分为成员变量(类变量和实例变量)和局部变量,作用域决定了变量的可见性和生命周期。Object类是所有Java类的基类,Java Bean规范定义了getter/...

    Lab02

    Scala是基于JVM(Java虚拟机)运行的,这意味着它可以利用Java的生态系统,同时提供了更简洁和强大的语法。"Lab02-main"可能包含了用于教学或练习的代码示例,帮助我们理解Scala的基本结构和语法。 在Scala中,一切...

    软件开发应知应会-84分.doc

    - 数据结构的研究包括数据的逻辑构造(如数组、链表)、存储构造(如顺序存储、链式存储)以及运算构造。 - 栈和队列是两种特殊的数据结构,它们的共同特点是只允许在端点处进行插入和删除操作,但栈遵循“后进先...

    akkaCustomMailbox:为 Java 工具包 Akka 实现自定义邮箱

    Akka 是一个强大的工具包,主要用于构建高度并发、分布式和反应式的应用程序,尤其在 Java 和 Scala 开发中广泛应用。在 Akka 中,"邮箱"(Mailbox)是用于存放消息的队列,它决定了Actor如何处理消息的顺序以及并发...

    javalruleetcode-cs-algorithms:CS算法实践repo

    java lru leetcode 算法 这个存储库提供了几个编程问题的代码片段。 这些问题是从各种来源阅读的。 只要有可能,就会有链接和问题一起呈现。 编程语言 我主要使用 Javascript、Typescript、Java 和 Scala。 您可以...

    软件开发应知应会-.pdf

    存储结构则是这些逻辑结构在内存中的实际表示,如顺序存储、链式存储等。此外,数据结构还包括对这些结构的操作,如查找、排序等。栈和队列是两种特殊的数据结构,它们的共同特点是只允许在端点处进行插入和删除操作...

    akka_new

    Akka 是一个用 Scala 编写的高性能、容错的并行计算框架,它极大地扩展了 Java 和 Scala 应用程序的并发处理能力。Akka 的核心理念是利用 Actor 模型来实现分布式计算,该模型简化了并发编程的复杂性,并提供了强大...

    函数与函数式编程

    函数式编程语言包括Haskell、Lisp、Erlang、Scala、F#等,但即使在非函数式语言如Python、Java或C#中,也可以采用函数式编程风格。这种编程风格的一个关键概念是高阶函数,即可以接受其他函数作为参数或返回函数的...

Global site tag (gtag.js) - Google Analytics