Java言語におけるstatic修飾子についての個人的まとめ
staticメンバについての認識が甘かったのでまとめてみる。以下のコードについて見ていく。知り合いの宿題。
サンプルコード
package homework;
import java.util.Scanner;
public class main {//mainクラス
public static void main(String[] args) {//main関数とその処理↓
new main().hw01();// ①自クラスmain()のhw01メソッドを実体にして(newして)起動
}
public void hw01() {//メソッド
Scanner s = new Scanner(System.in);
int a = s.nextInt();
int b = s.nextInt();
int c = s.nextInt();
checkTriangle(a, b, c);//②このメソッドが呼ばれる
}
private int checkTriangle(int a, int b, int c) {//③三角形の計算メソッド、今は重要ではない
assert a>0 && b>0 && c>0: "Impossible";
//if(a!=0 && b!=0 && c!=0) {
if((a<b+c) && (b<a+c) && (c<a+b)) {
if(a==b && b==c) {
System.out.println("���O�p�`");
}else if(a==b || a==c || b==c) {
System.out.println("�����O�p�`");
}else {
System.out.println("�O�p�`");
}
}
return 0;
}
}
staticメンバとインスタンスメンバの違い
(メンバとは、クラスのフィールド変数とメソッド(関数)のことを指す)
- staticメンバ:
クラス名.メソッド名
で実行できる。
-> 元々は、実態としてコンパイル前にメモリ上に存在している - インスタンスメンバ:
インスタンス名.メソッド名
で実行できる。
-> 元々は、実態ではなく設計図(クラス)のままで、インスタンス化するまでメモリには存在しないで、main関数実行中にnewでコピーして作成(インスタンス化)する
要は作成されるタイミングの違いと言うことができ、クラス=非実体、インスタンス=実体の違いという感じ。
これを踏まえて以下考える
hw01()メソッドを直接呼んだら良くない??って言われて挙動不審になった僕
A:「こうしたらエラーなのなんでなん??」
public class main {//mainクラス
public static void main(String[] args) {//main関数とその処理↓
Scanner s = new Scanner(System.in);
int a = s.nextInt();
int b = s.nextInt();
int c = s.nextInt();
checkTriangle(a, b, c);//まずい
}
private int checkTriangle(int a, int b, int c) {
//以下割愛
}
}
私:mainメソッド内にsっていうオブジェクト用意して、checkTriangleメソッドして起動、、、って感じで一見よくわからなかった。「ええんちゃう?」て。
このコード(staticメンバとインスタンスメンバの混合クラス)の問題点はなんでしょう?
答えは
簡単にいうと、
この問題を解決する方法を考えてみた。
-
checkTriangle()メソッド
にstaticをつける - main()関数のstaticを外す
- checkTriangle()メソッドをインスタンス化してmain関数内で呼び出す
もちろん 3. checkTriangle()メソッドをインスタンス化してmain関数内で呼び出す
が正解。
①:staticメソッドは継承したりできない。インスタンス化もできない
ので、「再利用したり使い回したり」ができない。後々オーバーライドしたり状態が変わったりする可能性があるならstaticメソッドにしてはいけないのである。
(むやみに車を作ってはいけないよね、後で車カスタマイズするときに困るよねw)
②:main()関数はいつでもランする時に呼ばれる関数(原始関数)なのでstaticにするべき。
(車に常に必要な部品は先に作っておこうぜ!)
-> Javaでは原則main()メソッドはstaticで宣言する
③:staticメソッド内では必ず「インスタンスメソッド」で関数を実行(=「すでに実態になったメソッド」を実行)しないといけない。(存在しているはずのstaticメソッド内にまだ設計書段階の処理は置けないよ、実態として確定させてよお!)
重要点
- メモリに前もって実態を作っておくのが「staticメソッド」
- newでコピーしてやっと実態になるのが「インスタンスメソッド」
よって
「staticメソッド内では「インスタンスメソッド」じゃないと実行できない」 のである。
最後に
エラー文としては、「Cannot make reference ... to the main()method」的なエラー文が出るはず。
「新わかりやすいJavaオブジェクト指向徹底解説」の3.2「メンバの仕組み」を参考にしました、ぜひ一読ください。
Discussion