Effective Java-Replace constructor with static factory method

Posted Jun 28, 20203 min read

First look at the code, this is boolean wrapper class Boolean, which has a static factory method inside.

public final class Boolean {

    public static final java.lang.Boolean TRUE = new java.lang.Boolean(true);

    public static final java.lang.Boolean FALSE = new java.lang.Boolean(false);

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

Static factory method advantages

  • Factory methods have method names. Usually we construct different objects by overloading the constructor. Sometimes we may pass in the same parameters, but the default values of other parameters are different. At this time, the constructor cannot Meet our requirements. And too many parameters are easy to cause errors and are not easy to understand. The static method name can describe the object to be returned, which is easier to use.
  • It is not necessary to create a new object every time, the static factory method can return the same object for repeated calls, such as Boolean, which has two predefined constants(TRUE, FALSE) inside, when we call Boolean. va lueOf(b oolean) will get one of them, and will not create a new object every time, which helps the class to always strictly control which instances should exist at a certain time, and also improve performance.
  • They can return objects of any subtype of the original return type, so that they are much more flexible in choosing the type of returned objects, such as:java.util.Collections.
  • The class of the returned object may change with each call, depending on the parameter value of the static factory method.
  • The class of the object returned by the method may not exist when writing the class containing the static factory method.

Disadvantages of the static factory method

  • Classes cannot be subclassed if they do not contain public or protected constructors. This is not all a disadvantage, because we are writing code to use more combinations and less inheritance.
  • Static factory methods are not easy to find, When we want to create an object of a class, we must consciously search for static factory methods in that class.

Common names for static factory methods

  • from one to one type conversion method, it has only a single parameter, returns a corresponding instance of the type, for example:

    Date d = Date.from(instant);

  • of aggregation method, with multiple parameters, returns an instance of the type, merge them together, for example

    Set faceCa ds = EnumSet.of(JACK, QUEEN, KING];

  • valueOf is a more cumbersome alternative than from of, for example

    Bigintege prime = Bigintege.valueOf(Intege.MAX_VALUE);

  • instance or get Instance-The returned instance is described by the method(if any) parameters, but it cannot be said to have the same value as the parameter, for example

    StackWalke luke = StackWalke.getinstance(options);

  • create or newInstance are just like instance or getinsta ce, but create or newInstance can ensure that each call returns a new instance, for example:

    Object newArray = Array.newInstance(classObject, Arraylen ;

  • getType- getInsta ce, but when the factory method is in a different class-let Typ represent the type of object returned by the factory method, for example:

    FileSto fs = Files.getFileStore(path);

  • newType one inch' is like newinstance, but when the factory method is in a different class, use Type to indicate the type of object returned by the factory method, for example:

    BufferedReade br = Files.newBufferedReade(path);

  • type-one-short version of getType and newType, for example:

    List litany = Collections.list(legacylitany ;

In short, both static factory methods and public constructors have their own usefulness. We need to understand that their respective strengths. Static factories are often more appropriate, because the first reaction is to provide public constructors without first considering static factories.