在这段代码中:
class Foo[T] {
def bar(i: T) = i
}
object Main {
def main(args: Array[String]) {
val f = new Foo[Int]
f.bar(5)
}
}
Run Code Online (Sandbox Code Playgroud)
bar
应首先调用整数.使用Scala 2.8.1进行编译并使用:
javap -c -l -private -verbose -classpath <dir> Main$
Run Code Online (Sandbox Code Playgroud)
看到为类的main
方法生成的字节码产生Main
:
public void main(java.lang.String[]);
...
9: iconst_5
10: invokestatic #24; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
13: invokevirtual #28; //Method Foo.bar:(Ljava/lang/Object;)Ljava/lang/Object;
16: pop
17: return
...
Run Code Online (Sandbox Code Playgroud)
您可以在通话BoxesRunTime
前看到通话bar
.
BoxesRunTime
是一个包含原始类型的装箱方法的对象,因此总共应该只有一个实例.这里的技巧是库中的这个特定文件是用Java编写的,转换是静态方法.出于这个原因,在运行时没有它的任何实例,尽管在Scala代码中使用它感觉就好像它是一个对象.
您可能应该使用JProfile查找盒装基元(例如java.lang.Integer),但我不确定JVM是如何工作的,以及它是否可以在运行时实际重写代码并优化它以避免装箱.据我所知,它不应该应用专业化(但我相信CLR确实如此).有和没有装箱情况的一些微基准测试是另一种弄清楚运行时会发生什么的方法.
编辑:
以上假设类型参数未使用注释进行@specialized
注释.在这种情况下,可以避免装箱/拆箱.标准库中的某些类是专用的.看到这个sid.
归档时间: |
|
查看次数: |
1256 次 |
最近记录: |