W tym kodzie:
class Foo[T] {
def bar(i: T) = i
}
object Main {
def main(args: Array[String]) {
val f = new Foo[Int]
f.bar(5)
}
}
Wywołanie bar
powinny pierwszym polu liczbę całkowitą. Kompilacja z Scala 2.8.1 i przy użyciu:
javap -c -l -private -verbose -classpath <dir> Main$
zobaczyć kodu bajtowego wyprodukowany dla metody main
rentowności Main
Klasa:
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
...
widać wywołanie BoxesRunTime
przed wywołaniem bar
.
BoxesRunTime
to obiekt, który zawiera metody bokowania dla typów pierwotnych, więc w sumie powinno być dokładnie jedno wystąpienie. Problem polega na tym, że ten konkretny plik w bibliotece został napisany w Javie, a konwersje są metodami statycznymi. Z tego powodu nie ma żadnych jego instancji w czasie wykonywania, chociaż użycie go w kodzie Scala wydaje się być obiektem.
Prawdopodobnie powinieneś szukać plików podstawowych w pudełku (np. Java.lang.Integer) w programie JProfile, ale nie jestem pewien, jak działa JVM i czy w rzeczywistości może on przepisać kod w czasie wykonywania i zoptymalizować go, aby uniknąć boksowania. Według mojej wiedzy, nie powinien on stosować specjalizacji (ale uważam, że CLR). Kilka mikrobańek z sytuacją boksu i bez niej to kolejny sposób, aby dowiedzieć się, co dzieje się w czasie wykonywania.
Edycja:
powyżej jest przy założeniu, że parametr typu nie opisywane z @specialized
adnotacji. W takim przypadku można uniknąć boksowania/rozpakowywania. Niektóre klasy w bibliotece standardowej są wyspecjalizowane. Zobacz this sid.
Specjalność występuje dla anonimowych klas funkcji "Test $$ anonfun $ #", ponieważ funkcje są wyspecjalizowane. Jednak te anonimowe klasy funkcji są używane w metodach 'map' i' filter', które nie są wyspecjalizowane i wywołują ich domyślny rodzajowy 'apply', który oczekuje obiektu - boks powinien tam wystąpić. Jeśli dekompilujesz kod 'TraversableLike' i szukasz' map' lub 'filter', powinny one wywoływać wywołania' BoxesRunTime'. – axel22