Javaの変数は大きく「プリミティブ型」と「参照型」の2種類に分類することができます。この変数のタイプを理解していないと、メモリ管理やデータ操作の際に予期せぬ挙動・バグを引き起こす可能性が高くなります。特に大規模なアプリケーション開発では、この理解がプログラムの効率性と安定性に非常に重要になってきます。
このページではJavaの変数の基本であるプリミティブ型と参照型の違いを端的にわかりやすく解説します。
関連 Javaの1stステップ:基本的な構文ルールを1分で復習!
プリミティブ型と参照型の違い
プリミティブ型と参照型の違いをわかりやすく表形式で整理しました。ポイントとなる部分を黄色ハイライトで示します。
特徴 | プリミティブ型 (Primitive Type) | 参照型 (Reference Type) |
---|---|---|
定義 | 変数に値を直接保持する | 変数にオブジェクトの参照を保持する |
例 | int , char , boolean など | String , 配列 , クラス のインスタンス など |
メモリ領域 | スタックメモリに格納される | ヒープメモリに格納される |
初期値 | int なら0 , boolean ならfalse などのデフォルト値 | null |
値の格納 | 直接値を格納する | オブジェクトのメモリアドレス(参照)を格納する |
値のコピー | 値そのものがコピーされる | 参照がコピーされる |
影響範囲 | 変更はその変数にのみ影響する | 変更は同じオブジェクトを参照するすべての変数に影響する |
例コード | int a = 10; int b = a; b = 20; | Person p1 = new Person("John"); Person p2 = p1; p2.setName("Jane"); |
メモリの状態 | a とb はそれぞれ独立して値を持つ | p1 とp2 は同じオブジェクトを指す |
プリミティブ型
プリミティブ型(Primitive Type)は、Javaで最も基本的なデータ型でザックリいえば「箱」のイメージが通用する変数です。(参考 プログラミングの「変数」とは?)
「箱」に値を格納して、その「箱」を使って様々な計算や処理を行っていくイメージ。
ポイント1 直接値を保持
プリミティブ型は、変数に直接値を保持する。つまり、変数そのものに数値や文字などの値が格納されます。
ポイント2 メモリ上の配置
プリミティブ型の変数は、メモリ上のスタックという領域に格納されます。スタックメモリは、変数の値を直接保持する高速なメモリ領域です。
ポイント3 値のコピー
プリミティブ型の変数を別の変数に代入すると、値そのものがコピーされます。元の変数と新しい変数は独立して存在し、一方の変更は他方に影響を与えません。
int a = 10; /*スタックメモリ: +-------+ | a | +-------+ | 10 | +-------+*/ int b = a; /*スタックメモリ: +-------+ +-------+ | a | | b | +-------+ +-------+ | 10 | | 10 | +-------+ +-------+*/ b = 20; /*スタックメモリ: +-------+ +-------+ | a | | b | +-------+ +-------+ | 10 | | 20 | +-------+ +-------+*/
プリミティブ型の動作原理は非常にシンプル。変数に直接値を保持し、変数間の代入は値そのものをコピーします。これにより、変数同士が独立して動作し、一方の変更が他方に影響を与えることはありません。
プリミティブ型として扱えるデータ型は以下の通り。
データ型 (Type) | サイズ (Size) | 範囲 (Range) | デフォルト値 (Default Value) | 説明 (Description) |
---|---|---|---|---|
byte | 8ビット | -128 ~ 127 | 0 | 小さな整数を保持する |
short | 16ビット | -32,768 ~ 32,767 | 0 | 中程度の整数を保持する |
int | 32ビット | -2,147,483,648 ~ 2,147,483,647 | 0 | 標準的な整数を保持する |
long | 64ビット | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | 0L | 大きな整数を保持する |
float | 32ビット | ±1.4E-45 ~ ±3.4E+38 | 0.0f | 単精度の浮動小数点数を保持する |
double | 64ビット | ±4.9E-324 ~ ±1.7E+308 | 0.0d | 倍精度の浮動小数点数を保持する |
char | 16ビット | '\u0000' (0) ~ '\uffff' (65,535) | '\u0000' | Unicode文字を保持する |
boolean | 1ビット | true または false | false | 真偽値を保持する |
参照型
参照型変数は、実際のデータ(オブジェクト)への「住所」を持つ変数です。データそのものを持っているのではなく、そのデータがメモリのどこにあるかを指しています。
参照型変数を日常生活の例えで説明すると以下のような関係。
- データそのもの:家
- 参照型変数:住所
参照型変数は、家そのものを持っているのではなく、家の住所を持っています。住所を知っていることで、その家に行くことができるというイメージです。
Person person1 = new Person("John", 25); /*スタックメモリ: +-----------+ | person1 | +-----------+ | (参照) | --> ヒープメモリの「John」という名前と「25歳」という情報を持つPersonオブジェクト +-----------+*/ Person person2 = person1; /*スタックメモリ: +-----------+ +-----------+ | person1 | --> | (参照) | +-----------+ +-----------+ | (参照) | | person2 | +-----------+ +-----------+ | (参照) | --> 同じヒープメモリのPersonオブジェクト +-----------+*/ person2.setName("Jane"); /*スタックメモリ: +-----------+ +-----------+ | person1 | --> | (参照) | +-----------+ +-----------+ | (参照) | | person2 | +-----------+ +-----------+ | (参照) | --> 同じヒープメモリのPersonオブジェクト(名前が「Jane」に変更) +-----------+ ヒープメモリ: +-------------------------+ | Person | +-------------------------+ | name: "Jane" | | age: 25 | +-------------------------+*/
サンプルコードのポイント1 person1の宣言と初期化
Person person1 = new Person("John", 25);
person1
という変数に、「John」「25歳」という情報を持つ「Person」という家の住所が割り当てられます。
サンプルコードのポイント2 person2にperson1の住所をコピー
Person person2 = person1;
person2
という変数にも、person1
と同じ家の住所が割り当てられます。つまり、person1
とperson2
は同じ家(同じデータ)を指しています。
サンプルコードのポイント3 person2を使ってデータを変更
person2.setName("Jane");
person2
を使ってその家の名前を「Jane」に変更します。person2
はperson1
と同じ家を指しているので、person1
を使っても名前は「Jane」に変わっています。
このように、参照型変数は「住所」を使ってオブジェクトを操作するイメージで捉えると理解しやすくなります。
プリミティブ型として扱うデータ型は以下の通り。
データ型 (Type) | 説明 (Description) | 例 (Example) |
---|---|---|
String | 文字列を保持するクラスです。文字の配列を扱います。 | "Hello" |
配列 (Array) | 同じ型の複数の値を保持するコンテナです。 | int[] nums = {1, 2, 3}; |
クラス (Class) | ユーザー定義のデータ型です。フィールドとメソッドを持ちます。 | Person p = new Person(); |
インターフェース (Interface) | クラスが実装するためのメソッドのセットを定義します。 | Runnable r = new MyRunnable(); |
列挙型 (Enum) | 固定された定数のセットを定義します。 | Day day = Day.MONDAY; |
ラッパークラス (Wrapper Class) | プリミティブ型をオブジェクトとして扱うためのクラスです。 | Integer num = 10; |