LoginSignup
5
4

More than 3 years have passed since last update.

Java: 5種類のstaticをさらっと説明する

Last updated at Posted at 2020-06-27

概要

Javaの「static」には5つの種類がある。しかし、それぞれは似て非なるものである。
本記事では、それぞれのstaticについて、落とし穴にハマらないための要点を説明する。
もっと詳しく知りたい場合は、記事最後の参考資料などを参照されたい。

1. staticメソッド

メソッドにstatic修飾子が付与されていると、staticメソッドとなる。

public static boolean equals(Object a, Object b) {
    return (a == b) || (a != null && a.equals(b));
}

staticメソッドは、インスタンスをnewしなくても呼び出すことができるため、一見便利に思える(使いやすそうに見える)。
しかし、単体テストを書きやすくするためには、「決まりきった処理」のみに利用すべきである。

2. staticフィールド

フィールドにstatic修飾子が付与されていると、staticフィールドとなる。

public static final double PI = 3.14159265358979323846;

上記のように、final修飾子と一緒に利用することで、定数として利用することができる。
final修飾子と一緒に利用することで、プログラムのどこかで値を書き換えられ、誤った計算結果を出力してしまうなどのバグを防ぐことができる。

なお、システムの設計によっては、キャッシュの保持などにも利用することができる。

3. 【中級者向け】staticインポート

外部のクラスのstaticフィールドや staticメソッドを、クラス名を指定せずに呼び出すことができるようになる。

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

public class SampleTest {
    @Test
    public void Test() {
        assertThat("foo", is("foo"));
    }
}

上記のサンプルでは、Assert.assertThatMatchers.isについて、クラス名を省略して記述することができている。

4. 【中級者向け】staticインナークラス

インナークラスにstatic修飾子が付与されていると、staticインナークラスとなる。

public class Outer {
  public static class Inner {
    // staticインナークラス
  }
}

非staticなインナークラスは親クラスのフィールドやインスタンスメソッドにもアクセスできる。
このため、親クラスへの参照を保持している。

しかし、不必要な親クラスへの参照は、メモリやGCへの悪影響1が懸念される。
インナークラスをstaticにできる状況であれば、staticにすべき2である。

5. 【中級者向け】staticイニシャライザ

下記のブロック内に記載した処理は、そのクラスに初めてアクセスされる時に呼び出される。

static {
  // 処理
}

具体的には、staticフィールドのコレクションの初期化などに利用する3

public static final List<String> LIST;
static {
    List<String> tmp = new ArrayList<>();
    tmp.add("foo");
    tmp.add("bar");
    LIST = Collections.unmodifiableList(tmp);
}

参考資料

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4