Java Design – Fully Static Classes: Pros and Cons

designdesign-patternsjavaobject-oriented-designstatic-access

I'm working on a larger solo project and right now, and I have several classes in which I do not see any reason to create an instance of.

My dice class right now, for example, stores all of its data statically and all of its methods are static too. I don't need to initialize it because when I want to roll the dice and get a new value, I just use Dice.roll().

I have several similar classes that only have one main function like this and I'm about to start working on a sort of "controller" class that will be in charge of all of the events (like when a player moves, and what current turn it is) and I've found that I could follow the same idea for this class. I don't ever plan on creating multiple objects for these specific classes, so would it be a bad idea to make them fully static?

I was wondering if this is considered "bad practice" when it comes to Java. From what I've seen, the community seems to be kind of split on this topic? Anyways, I would love some discussion on this and links to resources would be great too!

Best Answer

There is nothing wrong with static classes that are truly static. That is to say, there is no internal state to speak of that would cause the output of the methods to change.

If Dice.roll() is simply returning a new random number from 1 to 6, it's not changing state. Granted, you may be sharing a Random instance, but I wouldn't consider that a change of state as by definition, the output is always going to be well, random. It is also thread-safe so there are no problems here.

You'll often see final "Helper" or other utility classes which have a private constructor and static members. The private constructor contains no logic and serves only to prevent someone from instantiating the class. The final modifier only brings this idea home that this isn't a class you'd ever want to derive from. It is merely a utility class. If done properly, there should be no singleton or other class members which are not themselves static and final.

So long as you follow these guidelines and you're not making singletons, there is absolutely nothing wrong with this. You mention a controller class, and this will almost certainly require state changes, so I would advise against using only static methods. You can rely heavily on a static utility class, but you cannot make it a static utility class.


What is considered a change in state for a class? Well, lets exclude random numbers for a second, as they're nondeterministic by definition and therefore the return value changes often.

A pure function is one which is deterministic, which is to say, for a given input, you will get one and exactly one output. You want static methods to be pure functions. In Java there are ways of tweaking behavior of static methods to hold state, but they're almost never good ideas. When you declare a method as static, the typical programmer will assume right off the bat that it is a pure function. Deviating from expected behavior is how you tend to create bugs in your program, generally speaking and should be avoided.

A singleton is a class containing static methods about as opposite of "pure function" as you can be. A single static private member is kept internally to the class which is used to ensure there is exactly one instance. This is not best practice and can get you into trouble later for a number of reasons. To know what we're talking about, here is a simple example of a singleton:

// DON'T DO THIS!
class Singleton {
  private String name; 
  private static Singleton instance = null;

  private Singleton(String name) {
    this.name = name;
  }

  public static Singleton getInstance() {
    if(instance == null) {
      instance = new Singleton("George");
    }
    return instance;
  }

  public getName() {
    return name;
  }
}

assert Singleton.getInstance().getName() == "George"