0__*_*0__ 33 scala final field
vals(?)在单例对象中自动最终的原因是什么?例如
object NonFinal {
val a = 0
val b = 1
def test(i: Int) = (i: @annotation.switch) match {
case `a` => true
case `b` => false
}
}
Run Code Online (Sandbox Code Playgroud)
结果是:
<console>:12: error: could not emit switch for @switch annotated match
def test(i: Int) = (i: @annotation.switch) match {
^
Run Code Online (Sandbox Code Playgroud)
而
object Final {
final val a = 0
final val b = 1
def test(i: Int) = (i: @annotation.switch) match {
case `a` => true
case `b` => false
}
}
Run Code Online (Sandbox Code Playgroud)
编译时没有警告,因此可能会生成更快的模式匹配表.
必须添加final似乎纯粹恼人的噪音给我.这不是object最终本身,因此也是其成员?
Tra*_*own 25
最终类或对象的成员也是最终的,因此
final修饰符通常也是多余的.但请注意,常量值定义(第4.1节)确实需要显式final修饰符,即使它们是在最终类或对象中定义的.
你的final例子用2.10-M7编译时没有错误(或警告),所以我假设@switch早期版本的检查有问题,而且成员实际上是最终的.
更新:实际上这比我预期的更好奇 - 如果我们使用2.9.2或2.10-M7编译以下内容:
object NonFinal {
val a = 0
}
object Final {
final val a = 0
}
Run Code Online (Sandbox Code Playgroud)
javap 确实有所不同:
public final class NonFinal$ implements scala.ScalaObject {
public static final NonFinal$ MODULE$;
public static {};
public int a();
}
public final class Final$ implements scala.ScalaObject {
public static final Final$ MODULE$;
public static {};
public final int a();
}
Run Code Online (Sandbox Code Playgroud)
即使值定义的右侧不是常量表达式,您也会看到同样的事情.
所以我会留下我的答案,但这并不是决定性的.
psp*_*psp 21
你不是在问"他们为什么不是最终的",而是在问"他们为什么不进行内联".只是碰巧最后是你如何提示你希望它们内联的编译器.
它们未自动内联的原因是单独编译.
object A { final val x = 55 }
object B { def f = A.x }
Run Code Online (Sandbox Code Playgroud)
当你编译它时,Bf返回55,字面意思是:
public int f();
0: bipush 55
2: ireturn
Run Code Online (Sandbox Code Playgroud)
这意味着如果你重新编译A,B将无视这一变化.如果x在A中没有标记为final,则Bf看起来像这样:
0: getstatic #19 // Field A$.MODULE$:LA$;
3: invokevirtual #22 // Method A$.x:()I
6: ireturn
Run Code Online (Sandbox Code Playgroud)
另外,为了纠正其中一个答案,final并不意味着scala中的不可变.