PR

Java:static の意味と使い方を3分でわかりやすく解説

Java

Javaを学ぶ上で避けて通れないのが、staticキーワードです。結論から言うと、staticクラス全体で共有される変数メソッドを定義するために使われるキーワードで、このキーワードの使い方を学習することでクラスやインスタンスの動作原理/Javaにおけるメモリ管理の仕組みまで理解が進むようになります。

この記事では、Java初心者でも理解できるように、staticの使い方とその背後にある動作原理をステップバイステップで解説します。

関連 Javaの1stステップ:基本的な構文ルールを1分で復習!

スポンサーリンク

Java:staticとは何か?

staticは、クラスに属するメンバーを定義するためのキーワードです。(※メンバーとはクラスの中に定義される要素のこと。)

メンバーの種類説明
フィールドクラスやインスタンスのデータを保持する変数String name;(インスタンス用)
static int count;(クラス全体で共有)
メソッドクラスやインスタンスで使われる処理void run()(インスタンス用)
static void show()(クラス名で呼び出し)

通常、オブジェクト指向言語では、オブジェクト(インスタンス)ごとに変数やメソッドが存在します。しかし、staticを使うと、クラス全体で共有されるメンバーを作成できます。仮に、クラスが「学校」だとすると、通常の変数は「生徒一人ひとりの持ち物」、static変数は「学校全体で共有する校則」のようなものだと説明することができます。

ポイント1 通常の変数やメソッド

  • インスタンスごとに持つもの。例えば、「車」クラスのインスタンスであるカローラとプリウスはそれぞれ別々の色を持ちます。インスタンスを作るたびにメモリに割り当てられます。

ポイント2 static変数やメソッド

  • クラス全体で共有するもの。例えば、車クラス全体で共通の情報(セダン/SUV・・・)を持つときに使います。
  • クラスが最初に使われるとき(例えば、最初のインスタンスが作られるとき)に一度だけメモリに割り当てられます。その後、どのインスタンスからでも同じメモリを共有します。
Q
クラスとインスタンスの違いは?
A
  • クラス: 車の設計図のようなもの。車の特性(例えば、メーカーやモデル)や動作(例えば、走るや止まる)を定義します。
  • インスタンス: クラスに基づいて作られる実際の「もの」。車クラスから作られた具体的な車(カローラやプリウス)がインスタンスです。

staticキーワードの利用シーン

staticは主に変数、メソッド、ブロックの3つで使われます。ここからは具体的な利用シーンについて1個1個サンプルコードを用いながらその動作原理を解説していきます。

利用シーン概要
変数クラス全体で共有するデータを持たせたいときに使います。インスタンスごとではなく、1つの変数を全体で使い回します。static int totalCars; (全ての車の数を管理)
メソッドインスタンスを作らなくても、クラスから直接使いたい処理に使います。static void printInfo() (共通情報を表示するメソッド)
ブロッククラスが初めて使われたときに一度だけ実行したい初期化処理に使います。static { System.out.println("初期化完了"); }

static変数の使い方

static変数は、クラス全体で1つだけ存在する変数です。通常のインスタンス変数は各オブジェクトが個別に持ちますが、static変数は全てのオブジェクトで共有されます。

例としてクラスを「自動車メーカー」、オブジェクトを「個々の車」と考えてみましょう。インスタンス変数は各車が持つ「カラー」や「エンジンタイプ」のようなものです。一方、static変数はメーカー全体で共有する「生産台数」のようなもので、メーカー全体/メーカー共通で保持する変数になります。

宣言方法

public class Car {
    static String brand = "トヨタ"; // static変数の宣言
    String color; // インスタンス変数の宣言

    public Car(String color) {
        this.color = color;
    }
}

上記ではstaticキーワードを使って、brandというクラス全体で共有される変数を宣言しています。「色」は車個別ですが、ブランド名はそれらすべての車に共通するプロパティのため、staticキーワードの利用が適切です。

アクセス方法

  • クラス名で直接アクセス
public class Car {
    static String brand = "トヨタ"; // static変数の宣言
    String color; // インスタンス変数の宣言

    public Car(String color) {
        this.color = color;
    }
}

System.out.println(Car.brand); // 出力: トヨタ
  • インスタンスからもアクセス可能
public class Car {
    static String brand = "トヨタ"; // static変数の宣言
    String color; // インスタンス変数の宣言

    public Car(String color) {
        this.color = color;
    }
}

Car myCar = new Car("赤");
System.out.println(myCar.brand); // 出力: トヨタ
動作原理をイメージする

static変数は、プログラムの実行開始時にメモリ上に1つだけ確保されます。全てのインスタンスでこの1つの変数を共有するため、値の変更は全てのインスタンスに影響します。

システム的な視点

  • メモリ領域static変数はメモリの「メソッドエリア」に配置されます。この領域は、クラス情報やstaticメンバーが保存される場所です。

例え話で・・・

  • メーカーの「ブランド名」を掲げた看板のようなものです。この看板(static変数)は1つだけ存在し、全ての車(インスタンス)がそのブランド名を共有しています。

staticメソッドの使い方

staticメソッドは、インスタンスを生成しなくてもクラス名で直接呼び出せるメソッド(クラス全体で定義されているメソッドなので)です。

例え話:自動車メーカーが提供する「ブランド紹介ページ」のようなものです。特定の車(インスタンス)を持っていなくても、誰でもメーカー(クラス)のブランド情報(staticメソッド)を見ることができま

宣言方法

public class Car {
    static String brand = "トヨタ";

    static void showBrand() { // staticメソッドの宣言
        System.out.println("この車のブランドは " + brand + " です。");
    }
}

アクセス方法

  • クラス名で直接呼び出し
public class Car {
    static String brand = "トヨタ";

    static void showBrand() { // staticメソッドの宣言
        System.out.println("この車のブランドは " + brand + " です。");
    }
}

Car.showBrand(); // 出力: この車のブランドは トヨタ です。

staticブロックとは?その役割

staticブロックは、クラスがロードされるときに一度だけ実行されるコードブロックです。初期設定や複雑な初期化処理が必要な場合に使用します。

コードブロックとは、複数の処理を{ }で囲んだ部分のことです。Javaでは、ブロック内に書かれたコードが順に実行されます。

宣言方法

public class Car {
    static String brand;

    static {
        // staticブロック内での初期化
        brand = getBrandFromConfig();
    }

    static String getBrandFromConfig() {
        // ここでは固定値を返します
        return "トヨタ";
    }
}

staticブロックのポイント

  1. クラスが初めてロードされたときに一度だけ実行されます(newでインスタンスを作らなくても実行されます)。
  2. 複数のstaticブロックがある場合は、上から順に実行されます。
  3. static変数の初期化設定ファイルの読み込みなどに使われます。
利用シーン概要
変数クラス全体で共有するデータを持たせたいときに使います。インスタンスごとではなく、1つの変数を全体で使い回します。static int totalCars; (全ての車の数を管理)
メソッドインスタンスを作らなくても、クラスから直接使いたい処理に使います。static void printInfo() (共通情報を表示するメソッド)
ブロッククラスが初めて使われたときに一度だけ実行したい初期化処理に使います。static { System.out.println("初期化完了"); }

システム観点から見るstaticの動作原理

メモリとクラスローダー

メモリ領域の理解

  • メソッドエリアstatic変数やメソッド、クラスの情報が保存される領域。
  • ヒープ領域:インスタンス(オブジェクト)が保存される領域。

クラスローダーの役割

  • クラスローディングJVM(Java仮想マシン)が必要なクラスをメモリに読み込むプロセス。
  • ロードのタイミング:クラスが初めて使用されるとき。

staticの動作フロー

  1. クラスのロード:JVMがCarクラスをメモリに読み込みます。
  2. staticブロックの実行:クラスがロードされる際にstaticブロックが一度だけ実行されます。
  3. staticメンバーの利用可能static変数やメソッドが使用可能になります。

例え話で理解

  • 新しい車種(クラス)を生産するために、メーカーが工場を設立するイメージです。
    1. クラスのロード:工場の設立。
    2. staticブロックの実行:工場の初期設定や機械の調整。
    3. staticメンバーの利用可能:車の生産開始。

staticを使うメリット

staticキーワードを使うことで、クラス全体で共有するデータやメソッドを定義することができるようになる←これが1番のメリットで、この結果メモリの効率化やコードの簡潔さが向上します。

参考 メモリとは?

メリット1:メモリの効率化

static変数やメソッドは一度だけメモリに割り当てられ、全てのインスタンスで共有されます。これにより、同じデータを何度も作らずに済み、メモリの使用量を減らすことができます。

public class Car {
    public static String type = "Vehicle"; // static変数
    public String model; // インスタンス変数

    public Car(String model) {
        this.model = model;
    }
}

public class Main {
    public static void main(String[] args) {
        Car car1 = new Car("Corolla");
        Car car2 = new Car("Prius");

        System.out.println(Car.type); // "Vehicle"
        System.out.println(car1.model); // "Corolla"
        System.out.println(car2.model); // "Prius"
    }
}

メリット2:インスタンスを作らずに使える

staticメソッドや変数は、インスタンスを作らずに直接クラス名を使ってアクセスすることができる←これも大きなメリットになります。

public class MathUtils {
    public static int add(int a, int b) {
        return a + b;
    }
}

public class Main {
    public static void main(String[] args) {
        int result = MathUtils.add(5, 3);
        System.out.println(result); // 8
    }
}

MathUtils.addは、MathUtilsのインスタンスを作らずに使えます。

メリット3:共通データの管理が簡単

全てのインスタンスで共通のデータを管理する場合、staticを使うことでデータの一貫性を保ちやすくなります。例えば、あるクラス全体で共通の設定やカウンタを持たせる場合に便利です。

public class Config {
    public static String appName = "MyApp"; // static変数
}

public class Main {
    public static void main(String[] args) {
        System.out.println(Config.appName); // "MyApp"
        
        // 別の場所で変更しても全てに反映される
        Config.appName = "NewAppName";
        System.out.println(Config.appName); // "NewAppName"
    }
}

Config.appNameはどこからでもアクセス可能で、一度変更すれば全てに反映されます。

staticキーワードを使うことで、メモリの効率化、インスタンスを作らずに使える便利さ、共通データの一貫した管理が可能になる、という点がポイントです。

まとめ staticキーワードとは?

staticキーワードは、クラス全体で共有される変数やメソッドを定義するために機能です。このページでは車の例えを用いて、その動作原理をイメージしやすく説明してきました。

  • static変数:全ての車(インスタンス)で共有されるメーカーの情報(例:ブランド名)。
  • staticメソッド:特定の車を必要とせずに利用できる機能(例:ブランド紹介ページ)。
  • staticブロック:工場の初期設定を行う一度だけの処理。

システム的な理解

  • staticメンバーはメモリの特定の領域に保存され、プログラムの開始時にロードされます。
  • クラスローダーがクラスをロードするときにstaticブロックが実行され、static変数やメソッドが利用可能になります。

このWebサイトは現役のエンジニアが以下3点を目的として運営しています。

  1. 勉強:一度理解した内容を忘れないように。
    → アウトプットは「最強のインプット」である! 
  2. 備忘:忘れたとしても後から見返せるように。
    → 未来の自分への「お手紙」を書いています。 
  3. 共有:〇〇ってこうだったんだ!の感動をシェアできるように。
    → あなたの知識は誰かにとっての「価値ある情報」です。 

副業ブログの始め方はこちらから

スポンサーリンク
Java
シェアする
ビズドットオンラインをフォローする
タイトルとURLをコピーしました