Avoiding instantiation, private constructors or abstract classes?

Berkay Giris
2 min readMay 17, 2021

My story begins with the piece of Java code which I ran across in a pull request.

public class SomeConstants {    public static final String FAV_FOOD = "Pizza";
...some other constants
private SomeConstants() {
//preventing new instance
}
}

SomeConstants class is a small real-world example. It only includes some constant variables to be used globally across the application. So it will never ever be instantiated.

My conflict started with the private constructor. It works flawlessly by not allowing you to create an instance of SomeConstants. However, I didn’t like the idea of adding a piece of code, that is never going to be used, to prevent an unwanted action. The author even added a comment about why that constructor lies there.

It’s like saying I have the capability of creating myself, but I never will.

To be more explicit, I proposed making the class an abstract. That way, the class will never be instantiated. An abstract class is a conceptual meaning that will never occur by itself. Right..? In Effective Java, Joshua Bloch points out an issue with abstraction to enforce noninstantiability.

The class can be subclassed and the subclass instantiated. Furthermore, it misleads the user into thinking the class was designed for inheritance.

Remember, you are also not able to make it a final class to prevent instantiation. The two keywords conflict since one means that the structure is in its final form whereas, “abstract” implies it is just a flying thought. The reasoning behind this is detailed with an example in Can You Make An Abstract Class Final in Java.

Since there is no non-instantiable keyword or alike in the language, it looks like we have no other way than going with the private constructor smiling towards me quietly.

We just missed some point! As mentioned in the post, Avoid Utility Classes, sometimes it’s cheaper/easier to create a utility class rather than worrying about object-oriented design. It’s the procedural way of thinking. Although we all acknowledge the downsides of using utility classes, from time to time, we accept what we trade away and choose to have them. There is a freaking package named “java.util” out there.

In the end, Java is not designed for writing a constructor that would never be called. In a truly object-oriented context, there would be no final definitions of something noninstantiable. Hence we accepted that we are already away from the boundaries of object-oriented design, I can approve the pull request that bears a sneaky private constructor over there, peacefully.

--

--