型階層
型階層は以下の様に、AnyRefとAnyValに分かれています。
abstract class Any ├ class AnyRef extends Any 参照型の root クラス ├ sealed final class AnyVal extends Any 値型の root クラス └ final trait Nothing extends Any
Any は、Scalaのクラス階層の最上位クラスになります。
AnyVal型
Scalaは純粋オブジェクト指向言語で、全てがオブジェクトです。Java にあるプリミティブ型は存在しません。
scala パッケージには各プリミティブ型に対応した以下のようなクラスが定義されています。
// subrange types val c : Char = 'A' val b : Byte = 127 val s : Short = 200 // integer types val i : Int = 300 val l : Long = 400 // floating point types val f : Float = 500 val d : Double = 600 // boolean types val o : Boolean = true
int や boolean のような型はモジュール Predef で Scala クラスの型エイリアスとして定義されています。が、現在は非推奨となっています。
Javaのプリミティブ型との関係
IntやDouble、Booleanなどのクラスはクラスファイルへのコンパイル後は、対応するJavaのプリミティブ型として扱われます。
以下のソースにより作成されるクラスファイルを逆コンパイルしてみます。
object Main { def main(args : Array[String]) = { val i : Int = 100 println(i) } }
「Main.class」「Main$.class」の2つのクラスファイルが作成されます。それぞれのクラスの逆コンパイル結果は以下のようになります。(Scalaのバージョンは2.7.5を使用。インポート宣言などは削っています。)
Main.class
public final class Main { public static final void main(String args[]) { Main$.MODULE$.main(args); } public static final int $tag() throws RemoteException { return Main$.MODULE$.$tag(); } }
Main$.class
public final class Main$ implements ScalaObject { public Main$(){ } public void main(String args[]) { int i = 100; Predef$.MODULE$.println(BoxesRunTime.boxToInteger(i)); } public int $tag() throws RemoteException { return scala.ScalaObject.class.$tag(this); } public static final Main$ MODULE$ = this; static { new Main$(); } }
分かりにくいですが、int i と、プリミティブ型で扱われていることが分かります。