这是一个关于Scala如何编译的问题。有没有办法让编译后的代码直接引用 var 成员(getfield、putfield),而不是通过访问器函数(invokespecial、_$eq$
)?
我以为将 var 设置为 Final 就可以了,但事实并非如此。这是一个例子:
class foo {
private final var x: Int = 0
def incr { x += 1 }
def result: Int = x
}
这是 javap 的输出:
Compiled from "foo.scala"
public class foo {
private int x;
private final int x();
Code:
0: aload_0
1: getfield #13 // Field x:I
4: ireturn
private final void x_$eq(int);
Code:
0: aload_0
1: iload_1
2: putfield #13 // Field x:I
5: return
public void incr();
Code:
0: aload_0
1: aload_0
2: invokespecial #22 // Method x:()I
5: iconst_1
6: iadd
7: invokespecial #24 // Method x_$eq:(I)V
10: return
...
或者我应该不关心这个,因为 JVM 会内联访问器并且性能将是相同的?
下面是等效的 Java 代码:
class bar {
private int x;
void incr() { x += 1; }
int result() { return x; }
}
和字节码:
final class bar {
private int x;
void incr();
Code:
0: aload_0
1: dup
2: getfield #2 // Field x:I
5: iconst_1
6: iadd
7: putfield #2 // Field x:I
10: return
...
最佳答案
您可以使用private[this]
ref :
...
A private[C] where C is the outermost enclosing class is the same as just private in Java.
Finally, Scala also has an access modifier that is even more restrictive than private. A definition labeled private[this] is accessible only from within the same object that contains the definition. Such a definition is called object-private.
...
class foo {
private[this] final var x: Int = 0
def incr { x += 1 }
def result: Int = x
}
你得到
Compiled from "foo.scala"
public class foo {
private int x;
public void incr();
public int result();
public foo();
}
请注意,这通常会导致更丑陋的代码(恕我直言),因此如果这种性能提升并不重要,您应该避免它。
关于Scala 直接成员访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33453662/