こんにちは!雪犬です。
みなさんは、staticなメソッドと言われてstaticの意味を理解していますか?
この記事では、staticメソッドについて
- メソッドとは
- staticメソッドとは
- staticメソッドの書き方
- staticメソッドは遅い?早い?
など基本的な内容から、応用的な内容についても解説していきます。今回はstaticメソッドについて、使い方をわかりやすく解説します!
なお、Javaの記事については、こちらにまとめています。
メソッドとは(呼び出し方、引数、戻り値)
メソッドとは処理のひと塊のことです。変数や配列などの値を使って処理します。また、処理結果を取得することもできます。
メソッド外で定義されメソッド内の処理に使う変数や配列などを引数といいます。メソッド内ではこの引数、もしくはメソッド内で定義した変数やオブジェクトのみを使用することができます。処理した結果でメソッド外に渡す値のことを戻り値といいます。戻り値には変数やオブジェクトなどを1つ指定することができます。
メソッドを呼び出す場合は、そのメソッドを定義しているクラスをnew句を使ってインスタンス化して呼び出す場合とインスタンス化せずにクラス名で呼び出す場合があります。
staticメソッドとは
みなさんもメソッドや変数の前にstaticをつけることがありますよね。このstaticのついたメソッドや変数の事を「クラス変数」「クラスメソッド」と言います。クラス内固有に保持される変数やメソッドの事を指します。
反対にstaticのつかない非staticな変数やメソッドの事を、「インスタンス変数」「インスタンスメソッド」と言います。newで呼び出されたインスタンスで使われるもののことを指します。staticメソッドは、newを使わずに呼び出すことができます。
このstaticメソッドでは、staticな変数と引数で渡された値を使って処理を行います。非staticな変数やメソッドを使っての処理はできない事に注意してください。staticなクラスメソッド・クラス変数は実行時にすでにメモリに呼び出されています。
これに対し非staticな変数やメソッドは、newでインスタンス化した時にメモリに呼び出されます。staticなクラス変数は、処理の結果によって値が変わるのではなく、クラス毎で統一して持つ値になります。staticなクラスメソッド・クラス変数はそのクラスで共有して使われます。
staticなクラス変数はそのクラスで共有して使われ、どこで呼び出しても変わらない値になります。
staticメソッドの書き方
staticを付けたメソッドを定義します。
public class Cat { public static void method() { int count = 0; count++; } }
呼び出し方は以下のとおりです。
クラス名.メソッド名();
例えば以下のように記述します。
Cat.method();
クラスメソッドは、実行時にすでにメモリに呼び出され、その実体はクラスが持つことになります。インスタンスメソッドのようにnewでインスタンス化してから実体化されるわけではないのです。
staticメソッドは遅い?早い?
staticなクラスメソッドの処理が早いのかどうか、今回計ってみました。Catクラスをstaticなクラスメソッド、Dogクラスを非staticなメソッドとして、100000回ループしてそれぞれのメソッドを呼び出したときの処理速度を、ナノ秒単位で計測してみました。
計った結果は、ナノ秒なので多少の差しかありません。
ちなみに、
1ナノ秒 = 1秒の10億分の1
0.000000001sec = 1nanosec
の事です。
// Catクラス class Cat { static long count = 0; public static void method() { count++; } } // Dogクラス class Dog { long count = 0; public void method() { this.count++; } } // Mainクラス public class Main { public static void main(String[] args) { // Dogクラスをインスタンス化 Dog dog = new Dog(); long dogTime = 0; //Dogクラスの呼び出しの秒数 //Dogクラスの呼び出しの時のナノ秒 long dogCountStart = System.nanoTime(); for (int i=1; i<=100000; i++) { dog.method(); } long dogCountEnd = System.nanoTime(); dogTime = dogCountEnd - dogCountStart; // Catクラス(staticメソッド・static変数) long catTime = 0; long catCountStart = System.nanoTime(); for (int i=1; i<=100000; i++) { Cat.method(); } long catCountEnd = System.nanoTime(); catTime = catCountEnd - catCountStart; // 実行結果表示 System.out.println("Dog: " + dogTime + "ns"); System.out.println("Cat: " + catTime + "ns"); } }
実行結果:
非staticメソッド
1回目:2351449ns(0.002351449秒) 2回目:2666284ns 3回目:2301341ns 4回目:2321264ns 5回目:2800910ns
staticメソッド
1回目:926694ns(0.000926694秒) 2回目:1061321ns 3回目:1044418ns 4回目:927298ns 5回目:927298ns
こんな結果になりました。
今回検証を行った環境はJDK8です。この検証では、staticメソッドの方が早い結果になりました。
しかし、何度か実験を繰り返すうちにstaticメソッドの方が遅くなるケースもありました。ただ私が今回実行した結果だと、回数が多くなるとstaticメソッドの方が早くなる傾向でした。
そのため、一概にどちらが速い・遅いとは言えないようです。
static修飾子の使い方総まとめ
static修飾子のいろいろな使い方を次の記事にまとめているので、ぜひ確認してください!
まとめ
いかがでしたでしょうか?
今回のstatic変数・staticメソッドはクラスで共有され、クラスが持つものでした。クラスメソッドを作るときには、引数とクラス変数のみで作られるため、インスンタンス変数に左右されない処理をしたい時などに使えますね!
使いこなすことができるように、この記事を何度も参考にして下さいね!