Javaを学び始めると最初に登場する「クラス」と「インスタンス」という概念。「クラスは設計図、インスタンスはそれを元に作った実体」という説明はよく見かけますが、実際にJavaのコードでどう表現されるのか、thisは何を指しているのか、staticを付けると何が変わるのか、といった具体的な部分までは意外とまとまっていないことが多いです。
この記事では、Javaにおけるクラスとインスタンスの基本を、コード例を交えて紹介します。
対象読者
- Javaを触ったことがない、またはこれから触ろうとしている方
- 他言語の経験はあるが、Javaの「クラス」と「インスタンス」の違いを整理しておきたい方
- publicクラスの命名規則やコンストラクタ、
staticなど、Java特有のルールを一度確認しておきたい方
継承やポリモーフィズムといった発展的なオブジェクト指向の話や、JVMのメモリ管理の内部動作までは扱いません。あくまで「クラスとインスタンスとは何か」という最初の一歩に絞った内容です。
検証環境
Java 25(LTS、2025年9月リリース)を前提にしています。2026年3月にリリースされたJava 26は非LTSでサポート期間が6か月に限定されているため、学習用途で環境を作るなら、現行LTSであるJava 25を使うのが無難です。
クラスとインスタンス、結局何が違うのか
よく使われる説明は「クラスは設計図、インスタンスはその設計図から作られた実体」というたとえです。Oracleの公式チュートリアルでも、クラスはフィールド(データ)・メソッド(振る舞い)・コンストラクタ(初期化処理)から構成されるものだと説明されています。
クラスを定義しただけでは、まだ具体的なモノは何も存在しません。そのクラスを元にnewで実体化したものが、インスタンスです。
コード例:犬を表すDogクラス
犬を表すDogクラスを例に見てみます。
// Dog.java
public class Dog {
// フィールド(このクラスが持つデータ)
String name;
int age;
// コンストラクタ(インスタンス生成時の初期化処理)
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
// メソッド(このクラスができる振る舞い)
public void bark() {
System.out.println(name + ": ワン!");
}
}
Dogクラス自体は、「犬というものはこういうデータと振る舞いを持つ」という定義(設計図)です。この定義から、newを使って具体的な犬(インスタンス)を作ることができます。
// Main.java
public class Main {
public static void main(String[] args) {
Dog dog1 = new Dog("ポチ", 3);
Dog dog2 = new Dog("ハチ", 5);
dog1.bark(); // ポチ: ワン!
dog2.bark(); // ハチ: ワン!
}
}
Oracleの公式チュートリアルによると、newによるオブジェクト生成は「宣言(Declaration)」「インスタンス化(Instantiation)」「初期化(Initialization)」の3ステップで構成されています[^oracle-objectcreation]。new Dog("ポチ", 3)と書くと、Dogという同じ設計図からdog1という実体が作られ、コンストラクタによってnameとageが初期化されます。
ここでのポイントは、dog1とdog2は同じクラスから作られた別々のインスタンスであり、それぞれが独立したname・ageを持つという点です。一方のnameを書き換えても、もう一方には影響しません。「クラスは1つでも、そこから作られるインスタンスはいくつでも、それぞれ独立している」というのが、クラスとインスタンスの関係の基本になります。
thisキーワードの役割
コンストラクタの中でよく登場するのが、this.name = name;という書き方です。
public Dog(String name, int age) {
this.name = name; // 左辺: フィールドのname、右辺: 引数のname
this.age = age;
}
コンストラクタの引数名とフィールド名が同じnameになっているため、何も付けずにname = nameと書くと、どちらも引数のnameを指してしまい、フィールドへの代入にはなりません。this.nameと書くことで「これは引数ではなく、このインスタンス自身が持つフィールドの方だ」とコンパイラに伝えることができます。thisは「今まさに作られようとしている、このインスタンス自身」を指すキーワードです。
フィールドには「何もしなくても入る初期値」がある
Javaでは、フィールド(インスタンス変数)を明示的に初期化しなくても、型に応じたデフォルト値が自動で入ります。
| 型 | デフォルト値 |
|---|---|
byte / short / int
|
0 |
long |
0L |
float |
0.0f |
double |
0.0d |
char |
' ' |
boolean |
false |
Stringなど参照型 |
null |
先ほどのDogクラスで、もしコンストラクタでageを初期化し忘れていた場合、コンパイルエラーにはならずageは黙って0になります。一方でローカル変数(メソッド内で宣言する変数)にはこのデフォルト値の仕組みはなく、初期化せずに使おうとするとコンパイルエラーになります。フィールドかローカル変数かで挙動が異なる点は、押さえておく価値があります。なお公式チュートリアルでも、デフォルト値に頼った実装は行儀が良くないとされている点には注意が必要です。
staticを付けると「インスタンスをまたいで共有される変数」になる
フィールドにstaticを付けると、インスタンスごとではなくクラス全体で1つだけ共有される変数になります。
public class Dog {
String name;
int age;
static int numberOfDogs = 0; // クラス変数(全インスタンスで共有)
public Dog(String name, int age) {
this.name = name;
this.age = age;
numberOfDogs++;
}
}
Dog dog1 = new Dog("ポチ", 3);
Dog dog2 = new Dog("ハチ", 5);
System.out.println(Dog.numberOfDogs); // 2
nameやageはdog1とdog2でそれぞれ別の値を持つ「インスタンス変数」ですが、numberOfDogsはstaticが付いているため、dog1が作られてもdog2が作られても同じ1つの変数がインクリメントされていきます。公式チュートリアルでも、クラス変数へのアクセスはインスタンス名.変数名ではなくクラス名.変数名(例: Dog.numberOfDogs)の形で行うことが推奨されています。
Javaならではの注意点
最後に、Java特有のルールとして知っておくとよい点を2つ紹介します。
1. publicクラスの名前とファイル名は一致させる必要がある
public class Dogと宣言したクラスは、Dog.javaというファイルに書く必要があります。一致していない場合は、次のようなコンパイルエラーになります。
class Dog is public, should be declared in a file named Dog.java
1つのファイルに複数のクラスを書くこと自体は可能ですが、publicを付けられるクラスはファイルにつき1つまでで、そのクラス名とファイル名が一致している必要がある、というルールです。
2. コンストラクタを1つでも定義すると、引数なしコンストラクタは自動生成されなくなる
コンストラクタを一切定義しないクラスには、コンパイラが自動的に「何もしない引数なしコンストラクタ」を用意します[^oracle-objectcreation]。しかし、Dog(String name, int age)のようなコンストラクタを1つでも定義すると、この自動生成は行われなくなります。そのため、new Dog()のように引数なしでインスタンスを作りたい場合は、引数なしのコンストラクタも明示的に定義する必要があります。コンストラクタを追加した際に、これまで動いていた引数なしの生成がコンパイルエラーになる、というのはよくあるつまずきポイントです。
まとめ
- クラスは設計図、インスタンスは
newによってその設計図から作られる実体 - 同じクラスから作られたインスタンスでも、フィールドの値はそれぞれ独立している
-
thisは「今作られようとしているインスタンス自身」を指す - フィールドには型ごとのデフォルト値があるが、ローカル変数にはない
-
staticを付けたフィールドはインスタンス間で共有される - publicクラス名とファイル名は一致させる必要があり、コンストラクタを定義すると引数なしコンストラクタは自動生成されなくなる
クラスとインスタンスの関係は、Javaのオブジェクト指向を理解する上での出発点です。次のステップとして、継承やインターフェースといった、クラス同士の関係を扱う概念に進むのが自然な流れになります。
参考資料
- Classes | The Java™ Tutorials (Oracle)
- Creating Objects | The Java™ Tutorials (Oracle)
- Understanding Class Members | The Java™ Tutorials (Oracle)
- Primitive Data Types | The Java™ Tutorials (Oracle)
- Fix The Compile Error: class X is public should be declared in a file named X.java | Baeldung
- Java 26 正式リリース — ラーゲイト株式会社