[Java] Explain 5 types of static Java

2 minute read

Overview

There are five types of “static” in Java. But each is similar and different. In this article, I will explain the points for each static so as not to get caught in the pitfalls. For more details, refer to the reference materials at the end of the article.

1. static method

If a static modifier is added to the method, it becomes a static method.

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

The static method can be called without newing the instance, so it seems convenient (it seems easy to use). However, to make it easy to write unit tests, it should be used only for “fixed processing”.

2. static field

If the field is given the static modifier, it becomes a static field.

public static final double PI = 3.14159265358979323846;

As mentioned above, it can be used as a constant by using together with the final modifier. By using it with the final modifier, you can prevent bugs such as rewriting the value somewhere in the program and outputting incorrect calculation results.

Depending on the system design, it can also be used for holding a cache.

3. [For intermediate users] static import

It becomes possible to call static fields and static methods of external classes without specifying the class name.

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

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

In the above sample, class name can be omitted for Assert.assertThat and Matchers.is.

4. [For Intermediate] Static inner class

If the inner class has the static modifier, it becomes a static inner class.

public class Outer {
  public static class Inner {
    // static inner class
  }
}

The non-static inner class can also access the fields and instance methods of the parent class. Therefore, it holds a reference to the parent class.

However, unnecessary references to the parent class may cause a negative impact on memory and GC 1. If the inner class can be static, it should be static2.

5. [For intermediate users] static initializer

The process described in the block below is called when the class is accessed for the first time.

static {
  // process
}

Specifically, it is used to initialize the collection of static fields 3.

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

References

  1. https://spotbugs.readthedocs.io/ja/latest/bugDescriptions.html#sic-static-sic-threadlocal-deadly-embrace 

  2. https://spotbugs.readthedocs.io/ja/latest/bugDescriptions.html#sic-static-sic-inner-should-be-static 

  3. There is an opinion that the use of static initializer is redundant, but if the process becomes complicated, the judgment should be divided. Also think 

Tags:

Updated: