Answer: not static at all. A static inner class behaves like a normal class except that it is in the namespace of the outer class (“for packaging convenience”, as the official Java tutorial puts it).

So as an example:

public class Outer {
  private int x = 0;
  public int y = 1;
  
  static class Inner {
    //...
  }
}

As opposed to a true inner (nested) class, you do not need an instance of Outer to create an instance of Inner:

Outer.Inner inner = new Outer.Inner();

and Inner instances have no special knowledge about Outer instances. Inner class behaves just like a top-level class, it just has to be qualified as “Outer.Inner”.

Why I am writing about this?

Because I was quite shocked that two of my colleagues (both seasoned Java developers) were not sure if a static inner class was about static members and therefore global state.

Maybe they do not use static inner classes.

When do I use static inner classes?

I use a static inner class

  1. when it only of use for the outer class and it’s independent of the (private) members of the outer class,
  2. when it’s conceptionally tied to the outer class (e.g. a Builder class)
  3. for packaging convenience.

Often, the visibility of the static inner class is not public. In this case there is no big difference whether I create a static inner class or a top-level class in the same source file. An alternative for the first code example therefore is:

public class Outer {
  // ...
}
// not really inner any more
class Inner {
  // ... 
}

An example for (2) is a Builder class:

public class Thing {
  //...
  public static class Builder {
     // ... many withXXX methods
     public Thing make() // ...
  }
}

If the Inner instance needs access to (private) members of the Outer instance then Inner needs to be non-static.