こんにちは、Java歴7年で現在はフリーランスエンジニアをしているまさきと言います。
今回はJavaのstaticとインスタンス化の話をしていきます。
はじめに
まず初めにJava初心者の方に覚えてほしいstaticのルールがあります。
- static変数とstaticメソッドからは別クラスのstatic変数とstaticメソッドにアクセスができる。
- static変数とstaticメソッドからstaticではない変数とメソッドにアクセスはできないので、インスタンス化してからアクセスする。
例えば以下のクラスがあります。
public class Sample {
public static void main(String[] args){
int sum1 = add(1,2); //OK
System.out.println(sum1);
int sum2 = add(1,2,3); // NG
System.out.println(sum2);
}
public static int add(int num1, int num2){
return num1 + num2;
}
public int add(int num1, int num2, int num3){
return num1 + num2 + num3;
}
}
上記の例ではよくみるpublic static void mainの構文を使っていますが、こちらははstaticメソッドです。
staticメソッドからstaticメソッドであるadd(int num1, int num2)は問題ないです。
しかしstaticメソッドからstaticが指定されていないadd(int num1, int num2, int num3)は呼び出すとエラーになります。
これが初心者がつまずきやすいポイントです。
では詳しくstaticメソッドの使いかたを見ていきましょう。
staticとは
staticは簡単に言うと、指定した変数やメソッドはnewによるインスタンス化をしなくてもそのまま他のクラスから呼び出せる指定方法です。
staticはメソッドと変数に指定できますが、クラス宣言やコンストラクタには指定できないです。
staticは日本語で「静的」という意味で、クラスに静的に存在するメンバ(変数とメソッド)のことを表します。
staticの使いどころとしては、状態を持たず、変更がない静的な変数やメソッドに指定します。
どういうことかと言うと例えば、変数に付ける場合は更新がない定数だったり、メソッドの場合は状態を保持しないユーティリティと言われる共通機能に付けます。
定数の場合はこのようにクラスにまとめます。
//メッセージコードを管理するクラス
public class Message {
static final String LOGIN_ERROR = "error.login";
static final String LOGIN_SCCESS = "suucess.login";
}
このように書くことで他のクラスから定数を指定できます。
そしてもし変更があった場合はこの文字列の”error.login”に修正を加えれば変数名をわざわざ変える必要もなく、個別に修正する手間もなくなります。
ユーティリティクラスの場合はこのようになります。
//数値の計算をするクラス
public class NumberUtils {
public static int add(int num1, int num2){
return num1 + num2;
}
public static int divide(int num1, int num2){
return num1 / num2;
}
}
このメソッドを呼び出すときはこのようにします。
public class Main{
public static void main(String[] args){
int sum = NumberUtils.add(5, 10);
System.out.print(sum);
}
}
staticメソッドはインスタンス化をしなくてよいので、呼び出すときは「クラス名.staticメソッド名」となります。
staticのメリット/デメリット
staticのメリットは以下のようなことが挙げられます。
- インスタンスを作らず直接呼び出せる
- 共通して使う変数を管理できる
- 状態を保持しないのでいつ呼び出されても同じ動作を保証できる
逆に使う場合に注意しないといけないことはこちらです。
- staticではないインスタンス変数にアクセスできない
- staticではないメソッドでオーバーライドができない
- オブジェクト指向のよさが活かせない
staticを指定するかインスタンス化して使うか迷う場面が出てくると思いますが、こちらのメリットデメリットを考えて指定するようにしましょう。