Recently I've faced a question : How to avoid instantiating a Java class?
However, I answered by saying:
If you don't want to instantiate a class, use "abstract" modifier. Ex: javax.servlet.HttpServlet, is declared as abstract(though none of its methods are abstract) to avoid instantiation.
Declare a no argument private constructor.
Now my question is
a) are there any other ways?
b) why does any one do not want to instantiate a class? - after searching in SO, I got to know from this that Util classes can be made not to instantiate. Any other places where we don't want to instantiate a class in OOP?
Four reasons spring to mind:
- To allow subclasses but not the parent to be instantiated;
- To disallow direct instantiation and instead provide a factory method to return and if necessary create instances;
- Because all the instances are predefined (eg suits in a deck of cards) although since Java 5, typesafe enums are recommended instead; and
- The class really isn't a class. It's just a holder for static constants and/or methods.
As an example of (2), you may want to create canonical objects. For example, RGB color combinations. You don't want to create more than one instance of any RGB combo so you do this:
public class MyColor {
private final int red, green, blue;
private MyColor(int red, int green, int blue) {
this.red = red;
this.green = green;
this.blue = blue;
}
public static MyColor getInstance(int red, int green, int blue) {
// if combo already exists, return it, otherwise create new instance
}
}
Note: no no-arg constructor is required because another constructor is explicitly defined.
Not really an answer to your question but just a note:
When you make a private no-arg constructor to prevent instantiation of your utility classes, you should have the constructor throw an exception (e.g. UnsupportedOperationException). This is because you can actually access private members (including constructors) through reflection. Note that if you do so, you should accompany it with a comment, because it is a bit counter-intuitive that you define a constructor to prevent a class from being instantiated.
Making the utility class abstract is not a good idea because it makes the class look like it is intended to be extended, and furthermore you can extend the class and thereby instantiate it.
Sometimes you only want to avoid others instantiating your objects, in order to have full control over all existing instances. One example is the singleton pattern.
I think the most common reason for not wanting to instantiate a class is when you are dealing with a static class, and therefore with its static methods. You don't want someone to try to instantiate that class. Likewise, when you are dealing with Factory classes or in some cases many singleton classes will hide their constructor as to not be instantiated in the normal way.
Another way to make a class non-instantiable would be to declare it as a private inner class, and then not provide any way to instantiate it in the surrounding class. But this is (IMO) pretty pointless.
You want a class to be non-instantiable if it makes no sense to instantiate it. You generally do this if the class is really just a collection of (static) helper methods, or if the class is "incomplete". The incompleteness may be syntactically obvious (i.e. abstract methods), but there other kinds of incompleteness. For example, you might provide default default implementations for all methods, and require one or more of them to be overridden for the class to do something useful.
Another reason to make a class non-instantiable (or at least, not directly instantiable) is if your application needs to control the instantiation. For example, the java.util.regex.Pattern class cannot be directly instantiated so that the JRE can (could) maintain a cache of pre-compiled regexes.