14

ScalaAnyValとそのサブクラスは [C# 構造体や Java プリミティブのように] スタックに割り当てられますか? また、Scala での C# の構造体のように、カスタマイズされたスタック割り当て変数を作成できますか?

4

4 に答える 4

14

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 を明示的に使用すると、予想どおり、ヒープ上でボックス化されたプリミティブが発生します。

于 2012-07-12T08:43:48.557 に答える
8

AnyVal可能な場合、サブクラスはスタックに割り当てられます。AnyValオブジェクトがスコープをエスケープする場合、2.10.0を拡張する新しいユーザー作成クラスで例外が発生します。

AnyヒープにAnyVal保存されます...あなたが@specialized.

于 2012-07-12T21:37:07.323 に答える
3

JVMはジェネリックスの具体化をサポートしておらず、すべてのプリミティブ型に対してプリミティブスーパー型を持つ手段を提供していません。したがって、タイプのフィールドまたはパラメータAnyValは常にjava.lang.Objectバイトコードのタイプであり、ボックス化/アンボックス化が実行されます。

JVMは特定の最適化を実行する可能性があるため、これは必ずしも値がヒープに格納されることを意味するわけではありません。ただし、実行時のペナルティはまだ予想されます。

于 2012-07-12T08:49:35.193 に答える
3

私もScalaは初めてですが、私の知る限り、Scala変数には実際のオブジェクトを含めることはできません。最大でオブジェクトへの参照を含めることができます。(から参照を取得し、オブジェクトへのその参照をたどるnew逆参照演算子はありません(たとえばC++ など)。)*

つまり、すべての非プリミティブ値はヒープ上に存在します。(Java と同じです。)

于 2012-07-12T07:14:51.347 に答える