Are Scala's `AnyVal`s stack allocated?
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
}
So explicit AnyVal usage leads to boxed primitive on the heap, as expected.
AnyVal
subclasses are stack allocated, where possible. The exception happens with newer user-created classes that extend AnyVal
on 2.10.0, if the object escapes the scope.
Any
and AnyVal
will be stored on the heap... unless you @specialized
.
I'm also new to Scala, but AFAIK, a Scala variable can not contain an actual object. It can at most contain a reference to an object. (You get a reference from new
and there's no dereference operator to follow that reference to an object (such as *
in C++ for instance).)
In other words, all non-primitive values live on the heap. (Just as in Java.)