TLDR:不,它不是很好,但你可以指导编译器。
而且很容易检查(我把代码放到了test.scala中):
scalac test.scala
javap Foo.class
// Compiled from "test.scala"
// public class Foo {
// public int BUFFER_SIZE();
// public byte[] buffer();
// public Foo();
// }
所以 val 最终成为一个 getter 方法。现在让我们看看实际的字节码:
javap -c Foo.class
Compiled from "test.scala"
public class Foo {
public int BUFFER_SIZE();
Code:
0: aload_0
1: getfield #15 // Field BUFFER_SIZE:I
4: ireturn
// .... irrelevant parts
正如您所看到的,有一个getfield
代码意味着每个类实例都会有不同的实例(而不是getstatic
意味着访问静态变量)。高度优化的代码看起来像
public final int BUFFER_SIZE();
Code:
0: sipush 1024
3: ireturn
final
如果你用修饰符标记 BUFFER_SIZE 将会产生:
class Foo {
final val BUFFER_SIZE = 1024
val buffer = new Array[Byte](BUFFER_SIZE)
}
private[this]
使用@ghik 所说的前缀字段也可以解决问题。不同之处在于final
生成 getter 的代码很简单,而private[this]
直接内联值。