有如下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值
相关推荐
SCALA程序设计-JAVA虚拟机多核编程实战
资源名称:Scala程序设计:Java虚拟机多核编程实战资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
SpringBoot + SpringData Jpa + Scala + Mysql(java+Scala混编)
Scala到Java 用Scala编写的简单工具,揭示了Scala编译器的奥秘。 从StdIn读取scala代码,并将其反编译的Java版本写入StdOut。 用法 确保您已安装Java 1.8和Maven 检出项目 在项目目录中调用mvn clean package 。 ...
本书循序渐进地介绍了Scala的函数式编程基础,虽然篇幅短小,却切中要害。读者可以学会使用Scala静态语言的强大功能创建简洁、可扩展、高度可并行的代码。对于多核时代JVM上的并发编程,Scala是绝好的工具,而本书是...
Master the fundamentals of Scala and understand its emphasis on functional programming that sets it apart from Java. This book will help you translate what you already know in Java to Scala to start ...
赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...
博客配套文件,详细演示了在maven中如何混合编译java和scala共存的代码。
Scala集合Java开发Java经验技巧共9页.pdf.zip
scala-js-java-time, 在JDK8中,java.time的Scala.js 实现 scalajs-java-time scalajs-java-time 是用于的java.time API的bsd许可 reimplementation,它支持在 Scala.js 项目中使用这里 API 。用法只需将以
在Jelastic上使用Scala编程Java开发Java经验技巧共5页.pdf.zip
Martin Odersky 用他定义的匹萨语言给了 Java世界一个很大的冲击。尽管匹萨本身没有流行 但它展现了当把面向对象和函数型语言两种风格,技术地且很有品地混搭在一起时,就形成了 自然和强有力的组合。匹萨的设计成为...
图灵书籍包括Scala程序设计(第2版).pdf、Scala程序设计-JAVA虚拟机多核编程实战.pdf。
面向Java开发人员的Scala指南 面向Java开发人员的Scala指南
- Java源文件:9个,用于展示Java与Scala在Spark中的协同工作; - .gitignore文件:1个,用于Git版本控制时忽略不必要的文件; - .iml工程文件:1个,为IntelliJ IDEA项目配置文件。 本源码基于Spark进行全面精讲,...
赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...
可以用scala ,也可以用java,我主要的目的是用来判断汉字是否为繁体,
这些设计用于使用Java 8 lambda语法方便地构造Scala函数。 用法 import scala.concurrent.* ; import static scala.compat.java8.JFunction.* ; class Test { private static Future< Integer> futureExample ( ...
该demo是基于maven的scala(版本2.11.8)与java相互调用可以运行的最基本的例子。该demo可以导出可运行的jar文件。希望能对大家有帮助。