Scala の型について


型階層

型階層は以下の様に、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 と、プリミティブ型で扱われていることが分かります。