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.