ScalaAnyVal
とそのサブクラスは [C# 構造体や Java プリミティブのように] スタックに割り当てられますか? また、Scala での C# の構造体のように、カスタマイズされたスタック割り当て変数を作成できますか?
4 に答える
A.scala:
class A {
val a: AnyVal = 1
val b: Int = 1
}
scalac A.scala
javap -c A
public class A extends java.lang.Object implements scala.ScalaObject{
public java.lang.Object a();
Code:
0: aload_0
1: getfield #13; //Field a:Ljava/lang/Object;
4: areturn
public int b();
Code:
0: aload_0
1: getfield #16; //Field b:I
4: ireturn
public A();
Code:
0: aload_0
1: invokespecial #22; //Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: invokestatic #28; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
9: putfield #13; //Field a:Ljava/lang/Object;
12: aload_0
13: iconst_1
14: putfield #16; //Field b:I
17: return
}
そのため、AnyVal を明示的に使用すると、予想どおり、ヒープ上でボックス化されたプリミティブが発生します。
AnyVal
可能な場合、サブクラスはスタックに割り当てられます。AnyVal
オブジェクトがスコープをエスケープする場合、2.10.0を拡張する新しいユーザー作成クラスで例外が発生します。
Any
ヒープにAnyVal
保存されます...あなたが@specialized
.
JVMはジェネリックスの具体化をサポートしておらず、すべてのプリミティブ型に対してプリミティブスーパー型を持つ手段を提供していません。したがって、タイプのフィールドまたはパラメータAnyVal
は常にjava.lang.Object
バイトコードのタイプであり、ボックス化/アンボックス化が実行されます。
JVMは特定の最適化を実行する可能性があるため、これは必ずしも値がヒープに格納されることを意味するわけではありません。ただし、実行時のペナルティはまだ予想されます。
私もScalaは初めてですが、私の知る限り、Scala変数には実際のオブジェクトを含めることはできません。最大でオブジェクトへの参照を含めることができます。(から参照を取得し、オブジェクトへのその参照をたどるnew
逆参照演算子はありません(たとえばC++ など)。)*
つまり、すべての非プリミティブ値はヒープ上に存在します。(Java と同じです。)