
こんにちは。Javaエンジニア1年生です。
私はJavaの学習で1番最初に"インスタンス"の概念や"new演算子"、"static修飾子"の使い分けにつまづきました。
再びインスタンスが分からなくなった時に思い出せるよう、ゲームに例えて整理してみます。
この記事で分かること
この記事では、主に以下3点について深掘りします。
- インスタンスが必要なシチュエーション
- インスタンス化すると何が起こるのか
- インスタンス化しないと何が起こるのか
結論|インスタンスは"固有の状態を持つモノを作る時"に使う
インスタンスを使うタイミングは、"固有の状態を持つモノを作りたい時"です。 簡単に言うと、他のモノと干渉させたくない時に使います。
解説に入る前に、本記事で扱う基礎知識と前提を紹介します。
基礎知識・前提
クラス・インスタンス
多くの場面で、クラスは"設計図"、インスタンスは"実体・モノ"、インスタンス化(new)は"実体を作成する作業"と解説されます。
"設計図"であるクラスには、作りたいモノの"設定"が記載されているイメージです。
クラスをもとに作りたいモノを作成することをインスタンス化と呼びます。
本記事では作りたい"モノ"をインスタンスとして扱います。
new演算子
"new演算子"はインスタンス化の手段として利用されます。new演算子を使用してクラスをインスタンス化することで設計図の設定を実現します。
static修飾子
"static修飾子"をつけると、インスタンス化せずにクラス内の変数やメソッドを使用することができます。
クラスを設計図でなく、共通処理として扱う時などはstatic修飾子を使う場合があります。
ゲームで例える"インスタンス"
この章では"インスタンス"の概念を、武器やキャラクターを作成しキャラクター同士でバトルするゲームに例えて解説します。 キャラクター作成からバトル開始まで、以下の手順で進みます。
2. 武器作成
3. キャラクターに武器を装備
4. バトル開始
この手順のうち、1と2が"インスタンス化"に当てはまり、作成するキャラクターや武器のことを"インスタンス"と考えることができます。 次に、手順1~3をJavaで再現してみましょう。
ソースコードで見る"インスタンス"

まず手順1の"キャラクター作成"を行います。
作りたい1キャラクターを1インスタンスと考え、設計図となるCharacterクラスを作成します。設計図には以下の要素を設定します。
- キャラクター名
- 武器名
- 武器を装備
- 装備を表示
上記設定を反映したCharacterクラスを作成します。
class Character { String characterName;//キャラクター名 Weapon weapon;//武器名(武器インスタンス) Character(String name) {//コンストラクタ this.characterName= name; } void equipWeapon(Weapon weapon) {//武器を装備 this.weapon = weapon; } void showStatus() {//装備を表示 System.out.println(characterName + "の武器:" + weapon.name + "(攻撃力: " + weapon.power + ")"); } }
次に、mainメソッドでキャラクターを作成(インスタンス化)します。
Q. なぜインスタンス化するのか
例えば、"勇者"と"魔王"の2キャラクターを作成する時、互いに干渉(勇者の装備が魔王にも反映)する状態だとバトルが成り立ちません。 そのような時に"インスタンス化"が役立ちます。 本記事後半では、キャラクターごとに装備した武器が干渉しないことを、ソースコードの実行結果で確認します。
次のコードで実際にインスタンス化を行ってみましょう。
public class Main { public static void main(String[] args) { // ↓キャラクターをインスタンス化し作成 Character hero = new Character("勇者"); Character demonKing = new Character("魔王"); } }
上記のソースコードで勇者インスタンスと魔王インスタンスが作成され、手順1が完了しました。

次に、手順2の"武器作成"をキャラクター作成と同様の手順で行います。 設計図となるWeaponクラスには以下の要素を設定します。
- 武器名
- 攻撃力
class Weapon { String name;//武器名 int power;//攻撃力 Weapon(String name, int power) {//コンストラクタ this.name = name; this.power = power; } }
武器の設計図が完成したため、mainメソッドに武器を作成(インスタンス化)するソースコードを追記します。
public class Main { public static void main(String[] args) { // ↓キャラクターをインスタンス化し作成 Character hero = new Character("勇者"); Character demonKing = new Character("魔王"); // ↓各キャラクター用に別々の武器を作成 Weapon heroSword = new Weapon("勇者の剣", 500); Weapon demonWand = new Weapon("魔王の杖", 1000); } }
上記のソースコードで勇者の剣インスタンスと魔王の杖インスタンスが作成され、手順2まで完了しました。
ここから、手順3の"キャラクターに武器を装備"をmainメソッドに追記するため、修正を加えます。
public class Main { public static void main(String[] args) { // ↓キャラクターをインスタンス化し作成 Character hero = new Character("勇者"); Character demonKing = new Character("魔王"); // ↓キャラクターごとに別々の武器をインスタンス化し装備 hero.equipWeapon(new Weapon("勇者の剣", 500)); demonKing.equipWeapon(new Weapon("魔王の杖", 1000)); } }
手順2で記述したWeaponクラスのインスタンス化処理を、武器を装備するequipWeaponメソッドに渡す引数の中で行いました。一時的な変数(heroSwordなど)が不要となり簡潔に記述できます。
ここで、インスタンス化が本当に役立っているのか以下の処理を行い確認します。
- キャラクターごとに別々の武器を装備
- 勇者の武器のみ変更
- 魔王の武器に影響が無いか確認
public class Main { public static void main(String[] args) { // ↓キャラクターをインスタンス化し作成 Character hero = new Character("勇者"); Character demonKing = new Character("魔王"); // ↓キャラクターごとに別々の武器をインスタンス化し装備 hero.equipWeapon(new Weapon("勇者の剣", 500)); demonKing.equipWeapon(new Weapon("魔王の杖", 1000)); // ↓装備を表示 hero.showStatus(); demonKing.showStatus(); // ↓勇者のみ別の装備に変更 System.out.println("--- 勇者が武器を変更した! ---"); hero.equipWeapon(new Weapon("勇者の剣ex", 1000)); // ↓勇者のみ武器が変更されているか確認 hero.showStatus(); demonKing.showStatus(); } }
勇者の武器:勇者の剣(攻撃力:500) 魔王の武器:魔王の杖(攻撃力:1000) --- 勇者が武器を変更した! --- 勇者の武器:勇者の剣ex(攻撃力:1000) 魔王の武器:魔王の杖(攻撃力:1000)
実行結果から、各キャラクターの状態を分けて管理することに成功しました。 Main.java内14行目で勇者のみ別の武器(勇者の剣ex)に変更していますが、 魔王の武器に影響はなく、2キャラクターの武器が互いに干渉していないことを確認できました。
次の章では武器をインスタンス化しなかった場合を考えてみましょう。
"インスタンス化"しない場合
もし武器をインスタンス化しなかったらゲームの挙動はどうなるのか、ソースコードで確認しましょう。

Weaponクラスをインスタンス化せずに利用すると、武器が1種類しか存在しないゲームになります。
Weaponクラスの変数に変更が加わる度に、ゲームの世界全体の武器も書き換えられてしまうためです。
まずはインスタンス化せずに武器名や攻撃力を呼び出せるよう、本来は静的な値の定義に使うstatic修飾子を使ってWeaponクラスを作成しましょう。
class Weapon { static String name; static int power; }
次に、Characterクラスから武器インスタンスを除くため変数"weapon"を削除し、 Weaponクラスの変数を直接変更する処理に修正します。
class Character { String characterName; Character(String name) { this.characterName= name; } void equipWeapon(String name, int power) {//武器を装備 // インスタンス化せず、Weaponクラスの変数を変更 Weapon.name = name; Weapon.power = power; } void showStatus() {//装備を表示 System.out.println(characterName + "の武器:" + Weapon.name + "(攻撃力: " + Weapon.power + ")"); } }
最後に、mainメソッドで各キャラクターに装備した武器が姫インスタンスの変更によって影響されるか確認します。
public class Main { public static void main(String[] args) { Character hero = new Character("勇者"); Character king = new Character("王"); Character princess = new Character("姫"); // 勇者が武器を装備 hero.equipWeapon("剣", 100); hero.showStatus(); king.showStatus(); princess.showStatus(); System.out.println("--- 姫が武器を変更した! ---"); // 姫が武器を変えると… princess.equipWeapon("バターナイフ", 1); hero.showStatus(); king.showStatus(); princess.showStatus(); } }
勇者の武器:剣(攻撃力:100) 王の武器:剣(攻撃力:100) 姫の武器:剣(攻撃力:100) --- 姫が武器を変更した! --- 勇者の武器:バターナイフ(攻撃力:1) 王の武器:バターナイフ(攻撃力:1) 姫の武器:バターナイフ(攻撃力:1)
実行結果では、姫の武器変更によって全キャラクターの武器がバターナイフに変わりました。 固有の状態が変化する部分(武器)をインスタンス化しないと思わぬ部分に影響することがあります。
インスタンスの使いどころ
ゲームで例えたように、インスタンス化が必要になる場面は"固有の状態を分けて管理したい時"が挙げられます。
ここでは"インスタンスの使いどころ"を、インスタンス変数やクラス変数を比較しながら確認します。
※static修飾子を付けた変数/メソッドを、"クラス変数/メソッド"と呼びます。
"インスタンス変数/メソッド"と"クラス変数/メソッド"の違い
| インスタンス変数/メソッド | クラス変数/メソッド | |
|---|---|---|
| おすすめ用途 | 固有の状態を持たせたい | 固有の状態を持たない |
| 管理 | インスタンスごとに管理 | クラス全体で共通管理 |
| インスタンス化 | 必要 | 任意 |
| 例 | キャラクター | 今までに作成したキャラクター総数 |
インスタンス化する/しないの判断基準
インスタンス変数/メソッドを使いたい
→インスタンス化が必須
クラス変数/メソッドを使いたい
→インスタンス化は任意
まとめ|"固有の状態を持たせたい時"はインスタンス化
まとめると、インスタンス化する/しないは、
固有の状態を持たせたいかが1つの判断基準になると言えます。
私自身、研修中になんとなくnewしたりstaticをつけたりしていましたが、意図や根拠のある実装ができるよう知識を増やしたいと思いました。
ここまでお読みいただき、ありがとうございました。