Javaのプリミティブ型と参照型(クラス型)についてまとめる

Javaの型にはプリミティブ型と参照型(クラス型)の2種類の型が存在します。

それぞれについて説明します。

プリミティブ型の一覧

まずは基本となるプリミティブ型の一覧です。基本データ型、値型とか呼ばれたりもします。

種類 データ型の名前 サイズ
整数型 byte 8bit
short 16bit
int 32bit
long 64bit
浮動小数点型 float 32bit
double 64bit
文字型 char 16bit
論理型 boolean 1bit

プリミティブ型の詳細

longは19桁まで扱える。64bitなので最大値は
9,223,372,036,854,775,807

intは32bitなので、次のように求められる。
2^32 = 4,294,967,296

マイナスの値もあるので、整数として使用できる最大値は次のとおり。
2^32/2 = 2,147,483,648

intは10桁って覚えてたけど、32bitと覚えてた方が応用が利きそうだな。

桁数のサイズは byte > short > int > long で、

具体的には 8 > 16 > 32 > 64 って倍になっていく。

プリミティブ型で変数を宣言して値を代入すると、その変数は値そのものを保持します。値を保持するので、nullには出来ません。

これらの型の変数をメソッドに渡すと、値がコピーされて渡されます(値渡し)。

参照型(クラス型)について

String型、ArrayList型、Collection型、StringBuffer型など、すべてのクラスが参照型(クラス型)です。クラス型とも呼ばれ、クラス(=すなわちオブジェクト)になっています。そのため、先頭大文字で始まり、様々な型があり、それぞれメソッドを持ちます。

参照型はその名のとおりオブジェクトの参照を表しています。参照型で変数を宣言して値を代入すると、その変数はオブジェクトへの参照を保持します。

したがって、参照型の変数をメソッドに引数として渡すと、参照がコピーされて渡されます(参照の値渡し)。メソッド内で参照が指すオブジェクトの状態を変更すると、メソッドの外でもその変更が反映されます。

なお、String型は特殊で、参照型ですが不変(immutable)なので、新しい値を代入すると新しいインスタンスが生成されます。そのため、メソッド内でString型の引数を変更しても、メソッドの外から見ると変更されていないように見えます。

プリミティブ型との対応について

プリミティブ型には次のように、それぞれラッパークラスがあります。

byte: Byte
short: Short
int: Integer
long: Long
float: Float
double: Double
char: Character
boolean: Boolean

プリミティブ型にはnullをセットすることが出来ませんが、参照型はクラスなのでnullをセットすることも出来ます。

また、これらのラッパークラスにはプリミティブ型の値を操作するための便利なメソッドが多く提供されています。

Javaの自動ボクシングとアンボクシング機能により、プリミティブ型とそのラッパークラスの間で自動的に変換が行われることもあります。例えば、Integerオブジェクトをint型の変数に代入すると、自動的にアンボクシング(ラッパークラスからプリミティブ型への変換)が行われます。逆に、int型の値をInteger型の変数に代入すると、自動的にボクシング(プリミティブ型からラッパークラスへの変換)が行われます。

プリミティブ型と参照型(クラス型)のサンプル

メソッドにプリミティブ型の変数を渡すときに、その変数のコピー(値)が新たに作られ、それがメソッドに渡されます。そのため、そのメソッド内で変数の値を変えても、元の変数の値は変わりません。

一方、オブジェクト型の変数をメソッドに渡すときには、そのオブジェクト型の変数にはオブジェクトの「参照」が入っています。そのため、そのメソッド内でオブジェクトの状態を変更することができます。

void update(int value, StringBuffer bufferObj) {
    value = 30;
    bufferObj.append("world");
}

public static void main(String[] args) {
    int value = 20;
    StringBuffer bufferObj = new StringBuffer("Hello");
    update(value, bufferObj);
    System.out.println(value);        // 20を出力
    System.out.println(bufferObj);    // "Helloworld"を出力
}

valueの値はupdateメソッドの中で変更しても、mainメソッド内のvalueの値は変わりません。
一方、bufferObjは、そのオブジェクトの参照が渡されるので、updateメソッドの中でオブジェクトの状態を変更すると、mainメソッド内のbufferObjの状態も変わります。

以上、Javaのプリミティブ型と参照型(クラス型)のまとめでした。