⁉️

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 をコピーしたつもりが、妙な挙動に遭遇—そんな経験を掘り下げます。


はじめに

私はふだん PHPPython のような動的型付け言語で開発しています。しかし今夏から参加するインターン先では 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 との比較

  • すべてオブジェクト扱いだが、intstrimmutable
  • 代入は参照コピーなので、リストを共有すると片方の変更がもう片方にも影響。
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