在所有三種情況下,根本沒有裝箱。
這是很容易通過你的自我檢查:
class ActionId(val value: Int) extends AnyVal
object Foo {
def someFunction(): ActionId = {
new ActionId(123)
}
}
現在讓我們來運行scalac,我們將有一大堆的類文件(文件與字節碼)的。我們需要的是Foo \ $。
» javap Foo\$
Compiled from "Boxing.scala"
public final class Foo$ extends java.lang.Object{
public static final Foo$ MODULE$;
public static {};
public int someFunction();
}
正如您所看到的,即使值類通常從函數泄漏,它也不會被裝箱。
case class Post(id: ActionId, notion: String)
object Foo2 {
def someFunction(): Post = {
Post(new ActionId(123), "So ActionID will be boxed?")
}
}
scalac => javap的:
» javap Post
Compiled from "Boxing.scala"
public class Post extends java.lang.Object implements scala.Product,scala.Serializable{
public static scala.Function1 tupled();
public static scala.Function1 curried();
public int id();
public java.lang.String notion();
public Post copy(int, java.lang.String);
public int copy$default$1();
public java.lang.String copy$default$2();
public java.lang.String productPrefix();
public int productArity();
public java.lang.Object productElement(int);
public scala.collection.Iterator productIterator();
public boolean canEqual(java.lang.Object);
public int hashCode();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public Post(int, java.lang.String);
}
正如你可以看到ID這裏表示爲普通int(例如第三方法)。
最後,如果帶有值類成員的對象沒有被返回(真的不會逃避作用域),那麼值類會被裝箱嗎?
case class Post(id: ActionId, notion: String)
object Foo3 {
def anotherFunction(): Unit {
val post = Post(new ActionId(123), "Will be boxed?")
}
}
如果我們在方法的字節碼仔細一看,這裏就是我們將看到:
Code:
Stack=4, Locals=2, Args_size=1
0: new #15; //class Post
3: dup
4: bipush 123
6: ldC#17; //String Will be boxed?
8: invokespecial #20; //Method Post."<init>":(ILjava/lang/String;)V
11: astore_1
12: return
LocalVariableTable:
Start Length Slot Name Signature
0 13 0 this LFoo3$;
12 0 1 post LPost;
沒有在ActionId INT的拳擊。如果將框,你會看到這樣的事情之一:
Code:
Stack=5, Locals=2, Args_size=1
0: new #15; //class Post
3: dup
4: new #17; //class ActionId
7: dup
8: bipush 123
10: invokespecial #20; //Method ActionId."<init>":(I)V
13: ldC#22; //String Will be boxed?
15: invokespecial #25; //Method Post."<init>":(LActionId;Ljava/lang/String;)V
18: astore_1
19: return
LocalVariableTable:
Start Length Slot Name Signature
0 20 0 this LFoo3$;
19 0 1 post LPost;
你看,所不同的是bipush 123
與
4: new #17; //class ActionId
7: dup
8: bipush 123
10: invokespecial #20; //Method ActionId."<init>":(I)V
您可以想象庫支持在處理數組時處理語法開銷嗎? – ziggystar 2013-04-07 21:25:42
@ziggystar - 那麼,現在所有減少語法開銷的東西都會增加字節碼開銷。所以這是一個難以玩的遊戲。當它很重要時,你可以有一個值類包裝數組併爲你完成工作(只需很少的語法開銷),但我不確定如何使一個簡單的工廠,給定一個值類產生相應的數組價值班。我想,宏將最終到達那裏。 – 2013-04-07 21:30:02
@RexKerr這是否意味着數據結構中沒有值類?換句話說,List,Map等將始終實例化盒裝類? – 2015-05-12 21:16:30