S-JIS[2011-02-24] 変更履歴
scala.specializedアノテーションは、Javaのプリミティブ型を使うよう指示するアノテーション。Scala2.8以降。
型パラメーターを使ったクラス(やトレイト)を作った際、その型パラメーターがプリミティブ型相当で演算を行うなら、プリミティブ型の方が速くなる。
そこで@specializedを指定すると、プリミティブ型を使った特別なクラスが生成され、その型が使われる時は特別なクラスの方が使われる。
ただし、コンパイル時に
通常のクラスも作られ、プリミティブ型用のクラスもプリミティブ型の種類分だけ作られるので、クラスの個数が多くなる。
(C++のテンプレートも型引数の種類だけ作られるので、似た感じ)
// 全プリミティブ型 class Sample[@specialized T]
// 指定したプリミティブ型 class Sample[@specialized(Int) T]
// 複数の種類を指定 class Sample[@specialized(Int, Long) T]
@specializedの使用例。
例 | コンパイル結果(イメージ) | 備考 | |
---|---|---|---|
通常 |
class Sample[T] { def f(n: T) = n } |
public class Sample { public Object f(Object n) { return n; } } |
クラスの実体の引数・戻り値はObjectになるので、 呼び出し時はボクシングされる。 |
val s = new Sample[Int] val r = 1 + s.f(123)) |
Sample s = new Sample(); int r = 1 + ((Integer)s.f(Integer.valueOf(123))).intValue(); |
||
特別 |
class Sample[@specialized(Int) T] {
def f(n: T) = n
}
|
public class Sample { public Object f(Object n) { return n; } public int f$mcI$sp(int n) { return ((Integer)s.f(Integer.valueOf(n))).intValue(); } } public class Sample$mcI$sp extends Sample { public int f(int n) { return f$mcI$sp(a); } @Override public int f$mcI$sp(int n) { return n; } @Override public volatile Object f(Object n) { return Integer.valueOf(f(((Integer)n).intValue())); } } |
@specializedを付けると、汎用のメソッドと、そのプリミティブ型に特化したメソッドが作られる。 さらにそのクラスを継承した専用クラスが作られる。 |
val s = new Sample[Int] val r = 1 + s.f(123)) |
Sample$mcI$sp s = new Sample$mcI$sp(); int r = 1 + s.f$mcI$sp(123); |