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.