An example is worth a thousand words:
class A { def foo: Any = new Object }
class B extends A {
override def foo: AnyVal = 42
}
In Java, the signature @Override public int foo()
wouldn't even be allowed, and the overridden method foo
in B
could only return the wrapper integer type (@Override java.lang.Integer foo()
).
Is Scala able to avoid the boxing/unboxing of AnyVal
values in the overridden def foo: AnyVal
method above?
No, it does not. Scala has to adhere to emitting the correct bytecode:
λ scalac -Xprint:jvm Bar.scala
[[syntax trees at end of jvm]] // Bar.scala
package yuval.tests {
class A extends Object {
def foo(): Object = new Object();
def <init>(): yuval.tests.A = {
A.super.<init>();
()
}
};
class B extends yuval.tests.A {
override def foo(): Object = scala.Int.box(42);
def <init>(): yuval.tests.B = {
B.super.<init>();
()
}
}
}
You can see that although AnyVal
was permitted in Scala, the actual method signature for the emitted foo
is Object
and not AnyVal
, and Int
is boxed.