14

ScalaAnyVal及其子类 [可以] 堆栈分配 [如 C# 结构或 Java 原语]?我们可以像 C# 在 Scala 上的结构一样制作自定义的堆栈分配变量吗?

4

4 回答 4

14

斯卡拉:

class A {
  val a: AnyVal = 1
  val b: Int = 1
}

scalac A.scala

javap -c 一个

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

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

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

于 2012-07-12T07:14:51.347 回答
3

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

这并不一定意味着该值存储在堆上,因为 JVM 可能会执行某些优化。不过,您仍然必须期待运行时惩罚。

于 2012-07-12T08:49:35.193 回答