This is the 10th day of my participation in the August More text Challenge. For details, see: August More Text Challenge

preface

Why should we consider replacing constructors with static factory methods? What are its benefits and disadvantages? Here’s a brief introduction to the beauty of the static factory approach.

advantages

Static factory methods have names

Because static factory methods have names, it’s very convenient to know what they mean by the name. Otherwise, the user would have to read reference documentation or code to know what the different constructors are

You don’t have to create a new object every time you call it

        Integer tt = new Integer(1);
        Integer te = Integer.valueOf(1);
Copy the code

Let’s take a look at the two codes above. What’s the difference? It looks like they both return an Integer

   public Integer(int value) {
        this.value = value;
    }
Copy the code

When we call the constructor, we recreate the object every time

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
Copy the code

When we use valueOf, Java returns the same object for the number that falls into IntegerCache, thus avoiding the creation of unnecessary duplicate objects and greatly improving performance! However, it is important to note that this may cause some unsophisticated colleagues to use == to determine the value of Integer. When the returned value falls into IntegerCache, there will be no inequity problem, because it is the same object. However, if the actual environment exceeds [-128, 127] (127 can be set by parameter), then this may be different, and there will be potential bugs.

An object that can return any subtype of the original return type

You can return any subclass you want. One application is to make it possible for the API to return objects without the object’s classes becoming public. Hiding the implementation class in this way makes the interface very concise.

Before Java 8, you couldn’t have static methods in an interface, and we relied on unimplementable classes to implement them

After Java8, we can now have static methods in our interfaces, so providing unimplementable classes for interfaces is already just because static methods in interfaces must be public. Static methods can now be private in Java 9, but fields still need to be public.

The return class can vary depending on the argument

Each time we call a static factory method, we can, if we want, determine which subclass of the parent class to return from the parameter values of the method. Constructors cannot do this.

EnumSet is declared as an abstract class type. There are two implementations of EnumSet (RegularEnumSet and JumboEnumSet), but these two implementations are package private. It cannot be accessed outside the package, so you must use factory methods to create and return EnumSet instances, not constructors.

    / / noneOf method
    public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) { Enum<? >[] universe = getUniverse(elementType);if (universe == null)
            throw new ClassCastException(elementType + " not an enum");
        if (universe.length <= 64)
            return new RegularEnumSet<>(elementType, universe);
        else
            return new JumboEnumSet<>(elementType, universe);
    }
Copy the code

If the number is less than or equal to 64, we use RegularEnumSet. If the number is greater than 64, we use JumboEnumSet. The user does not need to care which subclass is returned, as long as it works. This is why we use static factories for creation. Noahsnail.com/2016/09/27/…

Returns the class to which the object belongs, which did not exist when the class containing the static factory method was written

This is the foundation of a service provider framework, such as JDBC’s API, where multiple service providers implement a service, and the system provides multiple implementations for the service provider’s clients and decouples them from multiple implementations.

disadvantages

Classes may not subclass

Classes can’t be subclassed without constructors decorated with public or Protect, but that’s fine. It’s better to use composition instead of inheritance.

The static factory approach is too humble

At first glance, there is no difference between static factory methods and static methods. For example, if we want to find out how to implement an EnumSet, we might find that direct new does not work without searching. It’s a little difficult for us to figure out how to instantiate the class.