1. プリミティブ型と参照型の違い
Javaにはデータ型として プリミティブ型 と 参照型 の2つがあります。それぞれの違いを、メモリ内での動作を含めて簡単に説明します。
特徴 | プリミティブ型 | 参照型 |
---|---|---|
格納されるもの | 値そのもの | オブジェクトのメモリアドレス(参照値) |
メモリの格納場所 | スタックメモリ | スタック(参照)+ ヒープ(オブジェクト本体) |
代表的な例 | int , double , boolean , char | String , 配列、クラスのインスタンスなど |
値の変更による影響 | 独立して動作(他の変数に影響しない) | 同じオブジェクトを参照している場合、影響を受ける |
2. スタックとヒープの違い
Javaのメモリには大きく分けて スタックメモリ と ヒープメモリ があります。
項目 | スタックメモリ | ヒープメモリ |
---|---|---|
用途 | メソッド実行中のローカル変数を保存 | オブジェクトや配列など動的データを保存 |
格納されるデータ | プリミティブ型の値、参照型の参照値 | オブジェクト本体、フィールド(プリミティブ型含む) |
ライフサイクル | メソッドが終了すると自動的に解放される | ガベージコレクションにより不要時に解放 |
速度 | 高速 | 比較的遅い |
3. スタックとヒープの具体例
以下のコードを例に、スタックとヒープでデータがどのように管理されるかを確認しましょう。
public class Main {
public static void main(String[] args) {
int x = 10; // プリミティブ型
Dog dog = new Dog("Pochi"); // 参照型
System.out.println(x); // 10
System.out.println(dog.name); // Pochi
}
}
class Dog {
String name; // フィールドはヒープに保存
Dog(String name) {
this.name = name; // フィールドに値を格納
}
}
メモリ構造:
- スタックメモリ:
x
: 10(プリミティブ型)dog
: 0x1234(ヒープ上のオブジェクトのアドレス)
- ヒープメモリ:
Dog
オブジェクト(アドレス 0x1234):name
: “Pochi”
4. String型が特別な理由
String
型は特別なクラスで、他の参照型と異なり Stringプール という仕組みを活用しています。
- Stringプールとは?
- ヒープメモリ内の特殊な領域で、文字列リテラルを共有・再利用します。
- 重複する文字列を節約してメモリ効率を上げるために存在します。
- 動作例:
public class Main {
public static void main(String[] args) {
String str1 = "hello"; // プール内に保存
String str2 = "hello"; // 同じ文字列を参照
String str3 = new String("hello"); // 新しいオブジェクトを作成
System.out.println(str1 == str2); // true (同じプール内の文字列)
System.out.println(str1 == str3); // false(異なるオブジェクト)
}
}
str1
とstr2
: Stringプール内の同じ文字列を参照。str3
: 新しくヒープにオブジェクトを作成。
5. メモリイメージ
+---------------------+ +---------------------+
| Stack | | Heap |
+---------------------+ +---------------------+
| local int x: 10 | | Address 0x1234 |
| local ref obj: 0x1234|----+ | ----------------- |
+---------------------+ | | Object { |
| | String name: |
| | "Pochi" |
| | } |
| +---------------------+
|
| +---------------------+
| | String Pool |
+--------->| "hello" |
+---------------------+
6. まとめ
- スタックはローカル変数や参照値を一時的に保存する短期メモリ。
- ヒープはオブジェクト本体や配列を保存する長期メモリ。
- String型は、メモリ効率化のためにStringプールを利用し、再利用可能な仕組みを持っています。