我写了以下非常简单的测试:
import scala.collection.immutable.HashSet
class Test {
def m() = {
var s = new HashSet[Int]
s = s + 1
}
}
Run Code Online (Sandbox Code Playgroud)
并想通了它编译成这段代码:
public class Test {
public void m();
Code:
0: new #12 // class scala/collection/immutable/HashSet
3: dup
4: invokespecial #15 // Method scala/collection/immutable/HashSet."<init>":()V
7: astore_1
8: aload_1
9: iconst_1
10: invokestatic #21 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
13: invokevirtual #25 // Method scala/collection/immutable/HashSet.$plus:(Ljava/lang/Object;)Lscala/collection/immutable/HashSet;
16: astore_1
17: return
public Test();
Code:
0: aload_0
1: invokespecial #30 // Method java/lang/Object."<init>":()V
4: return
}
Run Code Online (Sandbox Code Playgroud)
如您所见,1在使用1个元素创建新的不可变集之前,将其装箱.为什么装箱.Int extends AnyVal不是AnyRef.
确切地说Int extends AnyVal,不是AnyRef.但是,immutable HashSet[A]具有Aas参数,它不是专用于原始类型的,也就是说,它不是@specialized(Int) A或者类似的东西,所以它只能处理扩展的引用类型,AnyRef原始类型必须被加框.幸运的是,Scala编译器隐藏了这一点.