2.

Java の変数完全ガイド — 基本型・参照型・スコープ

編集
この記事の要点
  • Java の変数は 基本型 (primitive)参照型 (reference) の 2 種類
  • 基本型 8 種: byte / short / int / long / float / double / boolean / char
  • スコープは ローカル変数 / インスタンス変数 / クラス変数 (static) の 3 段階
  • final 変数は再代入不可。定数static final + UPPER_SNAKE_CASE
  • Java 10+ の var 型推論はローカル変数限定。フィールド・引数・戻り値には使えない

変数とは

変数は値を格納する名前付きの箱です。Java の変数は型 (type) を持ち、宣言時に決めた型と異なる値は格納できません(静的型付け)。

// 宣言と初期化
int age = 25;
String name = "Taro";
double pi = 3.14;
boolean isActive = true;

// 宣言だけ → 後から代入
int score;
score = 100;

// 複数同時宣言
int x = 1, y = 2, z = 3;

基本型 (primitive type) — 8 種

サイズ範囲初期値用途
byte8bit-128 〜 1270バイナリ / ファイル I/O
short16bit-32,768 〜 32,7670メモリ節約
int32bit約 ±21 億0★ 整数の標準
long64bit約 ±9.2 × 10^180L大きな整数 / タイムスタンプ
float32bitIEEE 7540.0f3D 座標等の単精度
double64bitIEEE 7540.0★ 浮動小数の標準
booleanJVM 依存true / falsefalse真偽値
char16bitUnicode 0 〜 655351 文字 (UTF-16 code unit)

※初期値はインスタンス変数 / クラス変数の場合。ローカル変数は初期化されないので、使う前に明示的に代入が必要です。

参照型 (reference type)

基本型以外はすべて参照型(クラス、配列、インターフェース、enum 等)。変数にはオブジェクトの参照(メモリアドレスに相当)が入ります。

String name = "Taro";        // String は参照型
int[] scores = {80, 90, 75}; // 配列も参照型
List<String> list = new ArrayList<>();

// 参照型のデフォルト値は null
String x;        // ローカルは未初期化 (使うとエラー)
class A { String y; }  // フィールドは null

// 参照のコピー (中身ではない)
int[] a = {1, 2, 3};
int[] b = a;       // 同じ配列を指す
b[0] = 99;
System.out.println(a[0]);  // 99 (a も影響を受ける)

スコープ (有効範囲)

種類宣言場所有効範囲初期値
ローカル変数メソッド / ブロック内宣言ブロック内無し (要明示初期化)
インスタンス変数クラス内 (static 無し)インスタンス生存中型既定値 (0 / false / null)
クラス変数 (static)クラス内 (static 付き)クラスロード中ずっと型既定値
仮引数メソッド引数メソッド内呼び出し時の値
public class User {
    static int totalCount = 0;   // クラス変数 (全インスタンス共有)
    private String name;         // インスタンス変数
    private int age;

    public User(String name, int age) {
        this.name = name;        // 仮引数 name とインスタンス変数 name を区別
        this.age = age;
        totalCount++;
    }

    public void greet() {
        String message = "Hello " + name;  // ローカル変数
        System.out.println(message);
        // message はここで消える
    }

    public void demoBlock() {
        for (int i = 0; i < 10; i++) {  // i のスコープは for 内
            int square = i * i;          // square も for 内
        }
        // System.out.println(i); // ★ コンパイルエラー
    }
}

final 変数 (再代入不可)

final int MAX = 100;
// MAX = 200;  // ★ コンパイルエラー

// 参照型の final は「参照」が再代入不可。中身は変えられる
final List<String> list = new ArrayList<>();
list.add("a");        // OK (中身を変更)
// list = new ArrayList<>(); // ★ NG (再代入)

// メソッド引数の final
public void process(final String input) {
    // input = "x";  // ★ NG
}

定数 (static final UPPER_SNAKE_CASE)

public class Constants {
    public static final int MAX_RETRY = 3;
    public static final String API_BASE_URL = "https://api.example.com";
    public static final double TAX_RATE = 0.10;
}

// 使用
int n = Constants.MAX_RETRY;

// インターフェースに定義する慣習もある (デフォルトで public static final)
public interface AppConfig {
    int TIMEOUT_MS = 5000;  // 自動的に public static final
}

var 型推論 (Java 10+)

右辺から型を推論してくれます。ローカル変数限定。フィールド・引数・戻り値には使えません。

// 良い使い方
var name = "Taro";                              // String
var list = new ArrayList<String>();             // ArrayList<String>
var map = Map.of("a", 1, "b", 2);               // Map<String, Integer>
var users = userRepository.findAll();           // 戻り値型が長いとき有効

// 悪い使い方
var x = null;                  // ★ コンパイルエラー (型を推論できない)
var n = 10;                    // int (long でも double でもなく int)
// 引数には使えない
public void f(var s) { }       // ★ NG

// for ループでも使える
for (var entry : map.entrySet()) {
    System.out.println(entry.getKey());
}

命名規則

対象規則
変数 / メソッドlowerCamelCaseuserName / calculateTax()
クラス / インターフェースUpperCamelCaseUserRepository
定数 (static final)UPPER_SNAKE_CASEMAX_RETRY_COUNT
パッケージすべて小文字com.example.app
boolean 変数is/has/can で始めるisActive / hasError

シャドーイング (同名変数の影)

public class Counter {
    private int count = 0;

    public void increment(int count) {
        // 仮引数 count がインスタンス変数 count を覆い隠す (シャドーイング)
        count++;                  // ★ 仮引数を増やすだけ (バグ)
        this.count = count;       // ✅ this. を付けてインスタンス変数を区別
    }
}

未初期化エラー

public void run() {
    int x;
    System.out.println(x);  // ★ コンパイルエラー: variable x might not have been initialized
}

// 分岐次第で未初期化になる場合もエラー
public int safeGet(boolean flag) {
    int v;
    if (flag) {
        v = 10;
    }
    return v;  // ★ flag が false のとき v が未初期化 → エラー
}

// ✅ 初期化を保証
public int safeGet2(boolean flag) {
    int v = 0;            // または初期化必須
    if (flag) v = 10;
    return v;
}

FAQ

Q: intInteger の違い
A: int は基本型 (4 バイトの数値そのもの)、Integer は参照型 (ラッパークラス)。Integer は null を持てるが、int は持てません。コレクションには Integer しか入れられない。

Q: String は基本型?
A: いいえ。String は参照型 (クラス)。ただしリテラル "abc" による生成は文字列プールで共有されるため、基本型のように振る舞います。

Q: final 変数は実行時 (動的) に代入してもいい?
A: 1 度だけならコンストラクタ等で遅延初期化可能 (ブランク final)。2 度目はコンパイルエラー。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 基本的なルール
  2. 変数
  3. 演算子
  4. 標準ライブラリ
  5. 外部ライブラリ
  6. 制御構文
  7. リスト(配列)
  8. タプル
  9. セット
  10. 辞書(dict)
  11. クラスとメソッド
  12. 継承の概念と必要性
  13. 継承の構文
  14. コンストラクタ
  15. cookieの値の設定と取得
  16. 例外処理
  17. 例外を文字列で出力する方法
  18. httpリクエスト(curl)をする方法
  19. Responseオブジェクトの中身の確認
  20. 変数が空かどうか判定する方法
  21. タイムゾーンの設定と現在日時の取得と文字列化
  22. シングルクォーテーションとダブルクォーテーションの違い

最近更新/作成されたページ