Javaで初心者向けに説明されている内容には「クラス」と「インスタンス」、「変数(プロパティ)」と「メソッド」の説明は出てくるのですが、「クラス変数」と「インスタンス変数」の説明まで踏み込まれたものが多くありません。
本記事では、Javaプログラミング学習中の方向けにクラス変数とは何か、インスタンス変数との違いまでサンプルコードを掲載しながらご紹介していきます。
目次
クラス変数とは
クラス変数は「static」で宣言する変数のことを指します。
クラス変数とインスタンス変数
クラス変数とインスタンス変数の違いは、staticとして宣言するかしないかによる違いです。
staticで宣言するクラス変数はインスタンス化せずにアクセスすることができ、staticを宣言しないインスタンス変数はクラスをインスタンス化しないとアクセスすることが出来ません。
またクラス変数はコンパイル時に作成されるのに対し、インスタンス変数はコンパイル時点では作成されないといった違いもあります。
クラス変数の宣言方法
クラス変数はstaticとして宣言すると上述してきましたが、具体的な宣言方法は下記となります。
アクセス修飾子 static データ型 変数名
クラス変数へのアクセス方法
クラス変数にアクセスするには下記のように記述します。
クラス名.変数名
クラス変数とグローバル変数・ローカル変数は意味合いが異なる
変数の解説では、クラス変数やインスタンス変数以外にもグローバル変数やローカル変数という言葉が出てきます。
インスタンス変数との違いは上述したので、グローバル変数とローカル変数との違いについても確認しておきましょう。
グローバル変数とローカル変数
グローバル変数とローカル変数の違いは、変数にアクセス可能な範囲の違いを表しています。
グローバル変数はあらゆる場所からアクセス可能な変数のことを意味しており、反対にローカル変数はメソッド内だけで利用される変数を指します。
クラス変数との違い
クラス変数はグローバル変数とよく勘違いされがちですが、あくまでクラス変数はクラス共有で使用する変数であり、アクセス修飾子は自由に決めることが可能です。
クラス変数とインスタンス変数が種類を区別しているのに対し、グローバル変数とローカル変数はアクセス範囲を区別しているイメージです。
Javaには厳密にはグローバル変数と呼ばれるものはありませんが、「public static」で変数を宣言することで、グローバル変数と似た機能として利用することが出来ます。
クラス変数と各種変数の違いをJavaサンプルコードで確認しよう
大まかなクラス変数についての情報は紹介出来ましたので、実際のサンプルコードで具体的に各種変数との違いを確認していきましょう。
クラス変数
まずはstaticを宣言して定義するクラス変数のサンプルコードです。
public class Main { public static void main(String[] args) { Sub.str1 = "テスト"; System.out.println(Sub.str1); // Sub.str2 = "テスト2"; private修飾子なのでアクセス出来ない Sub.setNum(2); Sub sub = new Sub(); System.out.println(sub.getNum()); } } class Sub { public static String str1; private static int num; public static int getNum() { return num; } public static void setNum(int num) { Sub.num = num; } }
実行結果が下記です。
テスト 2
public修飾子を付けたクラス変数の場合、4,5行目で値の設定・取得が可能であることを確認出来ます。
private修飾子を付けたクラス変数では、6行目の記述ではスコープ範囲外となってしまうため値を取得することは出来ません。
クラス変数で注目して頂きたいのが、7行目でインスタンス化せずにクラス変数の値を設定して、インスタンス化したクラス変数の値を9行目で取得した際、コンソール出力結果がインスタンス化する前に設定した値となっている点です。
これは、クラス変数がインスタンス単位ではなく、クラス単位で管理されることが理由です。
インスタンス変数
次は一般的に利用されるインスタンス変数のサンプルコードです。
public class Main { public static void main(String[] args) { Sub sub = new Sub(); sub.str1 = "テスト"; System.out.println(sub.str1); sub.setNum(5); System.out.println(sub.getNum()); } } class Sub { public String str1; private int num; public int getNum() { return num; } public void setNum(int num) { this.num = num; } }
実行結果が下記です。
テスト 5
まずクラス変数と決定的な違いとして、4行目のインスタンス化を実施しないとインスタンス変数にはアクセス出来ません。
インスタンス化した後は、public修飾子の変数であれば、直接呼び出し元から値の取得や変更が可能です。
private修飾子の変数に関しては、getやsetメソッドから変数の値を取得・変更します。
グローバル変数
グローバル変数が異なるパッケージのファイルからもアクセス出来るのか確認してみましょう。
Main.java
package sample; import sample.subDir.Sub; public class Main { public static void main(String[] args) { Sub.str = "テスト"; System.out.println(Sub.str); } }
Sub.java
package sample.subDir; public class Sub { public static String str; }
実行結果が下記です。
テスト
Main.javaの3行目に記述しているように、import文で参照先を明示する必要はありますが、読み込みが出来ていれば別ファイルからでもアクセス可能であることが分かります。
ローカル変数
メソッド内で定義される変数はローカル変数と呼ばれ、定義されたメソッド内でしか利用することが出来ません。
package sample; public class Main { public static void main(String[] args) { execute(); // localStr = "ローカル変数を変更"; スコープ外なのでアクセス不可 } private static void execute() { String localStr = "ローカル変数"; System.out.println(localStr); } }
実行結果が下記です。
ローカル変数
11行目で定義している変数がローカル変数で、7行目のようにメソッド外からローカル変数を呼び出そうとしてもエラーとなってしまいます。
さいごに: Javaのクラス変数と各種変数の役割を覚えておこう
本記事では、Javaにおけるクラス変数に関する情報を中心に、インスタンス変数やグローバル変数・ローカル変数との違いについてご紹介してきました。
クラス変数はクラスで共有する変数であり、インスタンス毎に変数の値が保持されるわけではない点に注意が必要です。
Javaでは基本的にインスタンス変数が利用されますが、使い方を理解した上でクラス変数をうまく利用出来るよう学習していきましょう。