是否已分配Scala的`AnyVal堆栈?

时间:2012-07-12 07:12:32

标签: scala

Scala AnyVal及其子类[可以]堆栈分配[如C#结构还是Java原语]?我们可以在Scala上创建一个自定义的堆栈分配变量,如C#的结构吗?

4 个答案:

答案 0 :(得分:12)

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使用会导致堆上的盒装基元,如预期的那样。

答案 1 :(得分:5)

在可能的情况下,

AnyVal子类是堆栈分配的。如果对象转义范围,则在2.10.0上扩展AnyVal的新用户创建的类会发生异常。

AnyAnyVal将存储在堆中......除非您@specialized

答案 2 :(得分:2)

我也是Scala的新手,但是AFAIK,Scala变量不能包含实际对象。它最多可以包含对象的引用。 (您从new获得引用,并且没有解除引用运算符跟随引用对象(例如C ++中的*)。)

换句话说,所有非原始值都存在于堆上。 (就像在Java中一样。)

答案 3 :(得分:2)

JVM不支持泛型的具体化,也没有为所有原始类型提供原始超类型的方法。因此,类型AnyVal的字段或参数在字节代码中将始终为java.lang.Object类型,并且将执行装箱/取消装箱。

这并不一定意味着值存储在堆上,尽管JVM可能会执行某些优化。但是你仍然需要运行时惩罚。