Consider static factory methods instead of constructors

Normally we create an object of a class using the public constructor but a good approach to creating an object is to use a static factory method instead of constructors.

Example of static factory method:

public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;
}

Advantages of static factory method

  • Unlike constructors, static factory method have names
  • Unlike constructors, they are not required to create a new object each time they’re invoked
  • Unlike constructors, they can return an object of any subtype of their return type
  • Static factories allow the class of the returned object to vary from call to call as function of input params
  • Static factories do not require the class of returned object to exist when the class containing the method is written

Disadvantages of static factory method

  • Classes without public/protected constructors cannot be subclassed.
    encourages composition over inheritance
  • Hard to find in the documentation

Unlike constructors, static factory method have names

public class User {
     
    private final String name;
    private final String country;
     
    public User(String name, String country) {
        this.name = name;
        this.country = country;
    }
     
    public static User getUserObject(String name, String country){
       return new User(name, country);
    }
}

Now call create the object: 
new User("Joe", "USA");
User.getUserObject("Sachin", "India"); // It has meaningful name

Unlike constructors, they are not required to create a new object each time they’re invoked

We can lazy load objects to make sure not to create a new object each time they are invoked.

public class MySingleton {
    private static MySingleton INSTANCE = null;
    private MySingleton() {} // private constructor
    public static MySingleton getInstance() {
        if (INSTANCE == null) {
            synchronized (MySingleton.class) {
                if (INSTANCE == null) {
                    INSTANCE = new MySingleton();
                }
            }
        }
        return INSTANCE;
    }
}

Some common names for static factory methods:

  • from()
  • of()
  • valueOf()
  • instance() or getInstance()
  • getType()
  • newType()
  • type()

Conclusion:

Avoid the public constructor and consider static methods/factories.