Javaにおけるstaticキーワード
Javaプログラミングにおいて、staticキーワードはしばしば使用されます。Javaのstaticキーワードは、Javaでのクラスレベルの変数を作成するために使用されます。static変数とメソッドはクラスの一部であり、クラスのインスタンスではないのです。
Javaのstaticキーワード
以下の画像で示されているように、Javaのstaticキーワードは5つのケースで使用することができます。ここではそのうちの4つについて説明しますが、5つ目のケースはJava 8で導入され、Java 8のインターフェースの変更で議論されています。
-
- Javaの静的変数
-
- クラスレベルの変数にはstaticキーワードを使用することができます。静的変数はクラス変数であり、クラスのオブジェクト/インスタンスには所属しません。静的変数はオブジェクトのすべてのインスタンスで共有されるため、スレッドセーフではありません。通常、静的変数はcommon resourcesやすべてのオブジェクトで使用される定数のようなものにfinalキーワードと共に使用されます。もし静的変数がprivateではない場合、ClassName.variableNameでアクセスすることができます。
-
- //静的変数の例
-
- private static int count;
-
- public static String str;
-
- public static final String DB_USER = “myuser”;
Javaの静的メソッド
静的変数と同様に、静的メソッドもクラスに所属し、クラスのインスタンスに所属しません。静的メソッドはクラスの静的変数のみにアクセスし、クラスの静的メソッドのみを呼び出すことができます。通常、静的メソッドは、他のクラスがインスタンスを作成する必要なく使用できるユーティリティメソッドです。たとえば、CollectionsクラスやJavaのWrapperクラス、ユーティリティクラスには多くの静的メソッドが含まれています。javaプログラムのエントリーポイントであるmain()メソッド自体も静的メソッドです。
//静的メソッドの例
public static void setCount(int count) {
if(count > 0)
StaticExample.count = count;
}
//静的ユーティリティメソッド
public static int addInts(int i, int…js){
int sum=i;
for(int x : js) sum+=x;
return sum;
}
Java 8以降では、インタフェース内でも静的メソッドを使用することができます。詳細については、Java 8のインターフェースの変更をお読みください。
Javaの静的ブロック
Javaの静的ブロックは、Javaのクラスローダによってクラスがメモリにロードされるときに実行される一連の文です。静的ブロックはクラスの静的変数を初期化するために使用されます。ほとんどの場合、クラスがロードされる際に静的なリソースを作成するために使用されます。静的ブロックでは非静的な変数にアクセスすることはできません。クラス内に複数の静的ブロックを持つことができますが、あまり意味を成しません。静的ブロックのコードは、クラスがメモリにロードされるときに一度だけ実行されます。
static{
//クラスがロードされる際にリソースの初期化に使用できます
System.out.println(“StaticExampleの静的ブロック”);
//静的な変数とメソッドにのみアクセスできます
str=”Test”;
setCount(2);
}
Javaの静的クラス
ネストしたクラスにはstaticキーワードを使用することができますが、トップレベルのクラスには使用することができません。静的なネストクラスは他のトップレベルクラスと同じであり、単にパッケージングの便宜上ネストしているだけです。詳細は: Java Nested Classes を参照してください。
サンプルプログラムの中で、Javaのstaticキーワードの使用方法を見てみましょう。StaticExample.java
package com.scdev.misc;
public class StaticExample {
//static block
static{
//can be used to initialize resources when class is loaded
System.out.println("StaticExample static block");
//can access only static variables and methods
str="Test";
setCount(2);
}
//multiple static blocks in same class
static{
System.out.println("StaticExample static block2");
}
//static variable example
private static int count; //kept private to control its value through setter
public static String str;
public int getCount() {
return count;
}
//static method example
public static void setCount(int count) {
if(count > 0)
StaticExample.count = count;
}
//static util method
public static int addInts(int i, int...js){
int sum=i;
for(int x : js) sum+=x;
return sum;
}
//static class example - used for packaging convenience only
public static class MyStaticClass{
public int count;
}
}
テストプログラムで、静的変数、メソッド、静的クラスの使い方を見てみましょう。TestStatic.java
package com.scdev.misc;
public class TestStatic {
public static void main(String[] args) {
StaticExample.setCount(5);
//non-private static variables can be accessed with class name
StaticExample.str = "abc";
StaticExample se = new StaticExample();
System.out.println(se.getCount());
//class and instance static variables are same
System.out.println(StaticExample.str +" is same as "+se.str);
System.out.println(StaticExample.str == se.str);
//static nested classes are like normal top-level classes
StaticExample.MyStaticClass myStaticClass = new StaticExample.MyStaticClass();
myStaticClass.count=10;
StaticExample.MyStaticClass myStaticClass1 = new StaticExample.MyStaticClass();
myStaticClass1.count=20;
System.out.println(myStaticClass.count);
System.out.println(myStaticClass1.count);
}
}
上記のJavaの静的キーワードの例プログラムの出力は次の通りです。
StaticExample static block
StaticExample static block2
5
abc is same as abc
true
10
20
クラスがメモリに読み込まれると、静的ブロックコードが最初に実行され、一度だけ実行されることに注意してください。他の出力は、自己説明的です。
Javaの静的インポート
通常、クラスリファレンスを使用して静的メンバーにアクセスしますが、Java 1.5からはクラスリファレンスを避けるためにJavaの静的インポートを使用することができます。以下にJava静的インポートの簡単な例を示します。
package com.scdev.test;
public class A {
public static int MAX = 1000;
public static void foo(){
System.out.println("foo static method");
}
}
package com.scdev.test;
import static com.scdev.test.A.MAX;
import static com.scdev.test.A.foo;
public class B {
public static void main(String args[]){
System.out.println(MAX); //normally A.MAX
foo(); // normally A.foo()
}
}
以下の通り、日本語での表現を一つ提示します:
インポート文に注意してください。スタティックインポートの場合は、import staticに続けてクラスの完全修飾されたスタティックメンバーを使用する必要があります。クラスのすべてのスタティックメンバーをインポートする場合は、import static com.scdev.test.A.*;のように*を使用することができます。クラスのスタティック変数を複数回使用する場合にのみ使用するべきであり、可読性にはあまり良くありません。更新情報:最近、Javaのstaticキーワードについて説明するためのビデオを作成しました。以下のリンクからご覧ください。https://www.youtube.com/watch?v=2e-l1vb\_fwM