Javaコラム Javaエンジニアのためのお役立ちコラム

Javaのstaticについて基本から解説!

2020年10月27日
SE
Javaのstaticはどのような意味なのでしょうか。
PM
staticをフィールドやメソッドにつけると、静的であるという意味になります。静的の対義語は動的です。

Javaのstaticとは?


Javaにはstaticというキーワードがあります。これをフィールドやメソッドにつけると、静的であるという意味になります。静的の対義語は動的です。静的と動的とは何なのでしょうか?

Javaにおいて静的とは「最初から1つのみ存在する」、動的とは「インスタンスが生成されることで生まれ、いくつでも存在しうる」という意味になります。この記事ではstaticを付けることで静的になるフィールドとメソッドの動作について解説します。

staticフィールドの宣言

staticなフィールドは以下のようにクラスのメンバーとして宣言します。宣言時に値を代入して初期化できます。初期化しない場合は、intなどの数値型は0、boolean型はfalse、クラスの参照型はnullに自動的に初期化されます。

class TestClass {
static public int s_value = 1;
}

以下のようにメソッドの中で使うことはできません。staticフィールドを宣言できるのはクラスのメンバーとしてだけです。

public static void main(String[] args) {
static int s_value = 1;
}

staticフィールドの使い方

staticなフィールドは以下のように同じクラスのメソッドから呼び出せます。メソッドがstaticでも非staticでも問題ありません。

class TestClass {
static public int s_value = 1;

public void dispValue() {
System.out.println(s_value);
}

static public void dispValue_s() {
System.out.println(s_value);
}
}

また、別のクラスのメソッドからも以下のように「クラス名.フィールド名」で利用できます。

public class MainClass {
public static void main(String[] args) {
System.out.println(TestClass.s_value);
}
}

staticフィールドは1つしか存在しない

最初に述べたように、staticフィールドは1つしか存在しません。TestClassを利用した以下のJavaサンプルをご覧ください。

TestClass tc1 = new TestClass();
tc1.s_value = 3;
TestClass tc2 = new TestClass();
tc2.s_value = 5;
System.out.println(tc1.s_value); // tc1のs_valueとして表示してみる

これを実行すると「5」が表示されます。別々のインスタンスからアクセスしていても、staticフィールドの存在は1つだけということです。

staticイニシャライザについて

staticフィールドの初期化は宣言時に代入する以外に、staticイニシャライザを使うこともできます。以下のJavaサンプルをご覧ください。

class TestClass {
static public int s_value;
static final String s_str;

// staticイニシャライザ
static {
s_value = 3;
s_str = “”固定文字列です。””;
}
}

finalの場合は値が宣言時のまま固定になりますが、staticイニシャライザの中では初期化できます。なお宣言時に=で代入して、staticイニシャライザで別の値で初期化すると、staticフィールドは後者の値になります。ただし混乱を招くので、これは避けた方がいいでしょう。

インターフェースのstaticフィールド

Javaにはクラスとは別にインターフェースがありますが、そちらにもstaticなフィールドを持つことができます。ただし必ずfinalになります。

interface TestInterface {
static int s_value = 3;
}

この様に宣言して、

TestInterface.s_value = 4;

のように値を変更しようとするとエラーになります。以下のようにfinalを付けておけばわかりやすくなります。

interface TestInterface {
static final int s_value = 3;
}

staticメソッドについて

ここからはJavaのstaticなメソッドの使い方について解説します。staticなメソッドもstaticフィールドと同様に、newをせずに使うことができます。

class TestClass {
static public int s_value = 3;

static public void dispValue_s() {
System.out.println(s_value);
}
}

上のdispValueメソッドは、以下のようにして利用できます。

public class MainClass {
public static void main(String[] args) {
TestClass.dispValue_s();
}
}

同一クラスでもstaticから非staticにはアクセスできない

ただし、同じクラスでもstaticなメソッドは、非staticのフィールドやメソッドにはアクセスできません。

class TestClass {
public static int s_value;
public int value;

public void dispValue() {
System.out.println(value);
}

static public void dispValue_s() {
System.out.println(value);
dispValue();
}
}

上のJavaサンプルでは、dispValue_s()のvalueとdispValue()へのアクセスはどちらもエラーになります。

継承をした時のstaticメソッドの動作

staticメソッドは継承をした時に非staticメソッドと違った動作をします。以下のJavaサンプルをご覧下さい。

class OyaClass {
static public void dispValue_s() {
System.out.println(“”親クラスです””);
}
}

class SubClass extends OyaClass {
static public void dispValue_s() {
System.out.println(“”サブクラスです””);
}
}

public class MainClass {
public static void main(String[] args) {
OyaClass c = new SubClass();
c.dispValue_s();
}
}

staticメンバーは参照変数からのアクセスは避ける

実行すると以下のように表示されます。

親クラスです。

インスタンスはSubClassなのにOyaClassのstaticメソッドが呼び出されています。staticメソッドは同じ名前でもオーバーライドされず、参照変数に属するものが呼ばれるということです。

ただstaticフィールドの時も触れた通り、参照変数からstaticメンバーを呼ぶと混乱を招くようなことが多くなります。そのためワーニングも発生します。staticメンバーへのアクセスは「クラス名.staticメンバー名」で行いましょう。

インターフェースのstaticメソッド

Java 8からはインターフェースにstaticメソッドを記述できるようになりました。そしてJava 9からはそれをprivateにもできるようになっています。以下のようなことができるということです。

interface TestInterface {
public static void dispMessage() {
dispMessage_inner();
}

private static void dispMessage_inner() {
System.out.println(“”メッセージ表示。””);
}
}

public class MainClass {
public static void main(String[] args) {
TestInterface.dispMessage();
}
}

実行すると以下のように表示されます。

メッセージ表示。

SE
staticを付けることで静的になるフィールドとメソッドの動作についてよく理解できました。
PM
処理を高速化したい時は積極的にstaticメンバーを利用していきましょう。

Javaのstaticなフィールドやメソッドを使いこなそう

Javaのstaticについて解説しましたが、ご理解頂けましたでしょうか。インスタンスが不要なstaticメンバーはパフォーマンスが良いので、処理を高速化したい時は積極的にstaticメンバーを利用してください。


Javaでのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)

Search

Popular

recommended

Categories

Tags

Jobs