我在玩 Scala。我发现了 3 个有趣的东西(标题是第三个)。
1 声明为 val 的局部变量不会被解释为 final。
class HowAreVarAndValImplementedInScala {
var v1 = 123
val v2 = 456
def method1() = {
var v3 = 123
val v4 = 456
println(v3 + v4)
}
}
如果我将上面的 scala 代码编译成字节码,然后将其反编译成 java,它看起来像这样:
public class HowAreVarAndValImplementedInScala
{
private int v1 = 123;
private final int v2 = 456;
public int v1()
{
return this.v1;
}
public void v1_$eq(int x$1) { this.v1 = x$1; }
public int v2() { return this.v2; }
public void method1() {
int v3 = 123;
int v4 = 456;
Predef..MODULE$.println(BoxesRunTime.boxToInteger(v3 + v4));
}
}
我们可以看到 v2 是最终版本,但 v4 不是,为什么?
.net 的 2 scala 编译器为许多(如果不是全部)公共实例方法添加了 override 关键字
如果我们把上面显示的scala代码编译成CIL,然后反编译成C#,是这样的:
public class HowAreVarAndValImplementedInScala : ScalaObject
{
private int v1;
private int v2;
public override int v1()
{
return this.v1;
}
public override void v1_$eq(int x$1)
{
this.v1 = x$1;
}
public override int v2()
{
return this.v2;
}
public override void method1()
{
int v3 = 123;
int v4 = 456;
Predef$.MODULE$.println(v3 + v4);
}
public HowAreVarAndValImplementedInScala()
{
this.v1 = 123;
this.v2 = 456;
}
}
所有公共实例方法(不包括构造函数)都被标记为覆盖,为什么?有必要吗?
3 .net 的 Scala 编译器失去了 val 的含义
在上面的c#代码中,我们可以看到v2只是一个普通的字段,而在java couter部分,v2被标记为final,不应该被Scala编译器为.net标记为readonly吗?(一个bug? )