⁉️
Javaではint型とstring型で扱い方が違う?
Javaではint型とstring型で扱い方が違う?
みなさんは Java で次のようなコードを書いたときに、「あれ、思った動きと違う…?」 と感じたことはありませんか?
public class Mystery {
public static void main(String[] args) {
int x = 5;
int y = x;
y = 10;
System.out.println("x = " + x); // ➜ 5
String s1 = "hello";
String s2 = s1;
s2 = "world";
System.out.println("s1 = " + s1); // ➜ hello 期待と違った!
}
}
int と同じノリで String をコピーしたつもりが、妙な挙動に遭遇—そんな経験を掘り下げます。
はじめに
私はふだん PHP や Python のような動的型付け言語で開発しています。しかし今夏から参加するインターン先では Java での開発が必須。学習する中で、他の言語と大きく違うポイントに気づいたので共有します。
プリミティブ型と参照型の違い
Java の型は大きく プリミティブ型 (primitive types) と 参照型 (reference types) に分かれます。
| 分類 | 具体例 | メモリに保持するもの |
null 代入 |
メソッド呼び出し |
|---|---|---|---|---|
| プリミティブ |
int, double, boolean, char … |
値そのもの | × | × |
| 参照型 |
String, 配列, List, 独自クラス… |
オブジェクトのアドレス | 〇 | 〇 |
覚えておきたいポイント
- 値そのものか参照(アドレス)か が根本的な差。
-
Stringは参照型(オブジェクト)なので、==比較や代入の挙動がintとは違う。 - プリミティブ型は Wrapper クラス (
Integer,Doubleなど) を使えば参照型として扱える。
コードで見る挙動の違い
プリミティブ型は値コピー
int a = 5;
int b = a;
b = 10;
System.out.println(a); // 5
参照型は“参照”コピー
String s1 = "hello";
String s2 = s1; // s1 と同じ文字列オブジェクトを指す
s2 = "world"; // s2 だけ別オブジェクトを指すようになる
System.out.println(s1); // hello
🔑 Point:
Stringはイミュータブル(不変)なので、s2 = "world"で新しいオブジェクトが生成され、s1は元のまま。
もう少し“参照”らしさが見える例として配列を使います。
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1; // arr1 と同じ配列を参照
arr2[0] = 99;
System.out.println(arr1[0]); // 99
Python・PHPとの違い
| 観点 | Java | Python | PHP |
|---|---|---|---|
| 型付け | 静的 | 動的 | 動的 |
| プリミティブ型 | 8種類あり | すべてオブジェクト | 事実上なし (スカラはコピーオンライト) |
| 参照コピー時の挙動 | 参照を値渡し | すべてオブジェクト、mutable/immutable の違い | 配列はコピーオンライト、オブジェクトは参照 |
null/None
|
参照型のみ null 可 |
None |
null |
Python との比較
- すべてオブジェクト扱いだが、
intやstrは immutable。 - 代入は参照コピーなので、リストを共有すると片方の変更がもう片方にも影響。
nums1 = [1, 2, 3]
nums2 = nums1
nums2[0] = 99
print(nums1[0]) # 99
PHP との比較
- スカラ値はコピー、配列はコピーオンライト、オブジェクトは参照。
-
===と==の違いが Java のequals/==の関係に少し似ている。
$a = [1, 2, 3];
$b = $a; // コピーオンライト
$b[0] = 99;
print_r($a); // [1, 2, 3]
まとめ
- Java ではプリミティブ型と参照型を明確に区別 する必要がある。
-
Stringは参照型かつイミュータブル。==比較や代入の挙動に注意。 - Python/PHP 経験者は「値コピー vs 参照コピー」の違いをコードで試して体感すると理解が早い。
- Wrapper クラス・
equalsメソッドなど、Java 特有の落とし穴も要チェック!
💡 Tip: 疑わしいときは
System.identityHashCode()でオブジェクトの実体を確認すると参考になります。
次回は Wrapper クラスとオートボクシング について深堀りする予定です。お楽しみに!
Discussion