Effective Java-consider replacing constructors with static factory methods

Source: Internet
Author: User
Tags protected constructor

Effective Item-Consider a static factory method instead of a constructor we have two common ways to get an instance of a class:

    • Public constructors
    • Provides static factory methods (static Factory method)

The static factory method has the following advantages over the public constructor.

Advantage 1. The name of the static factory method, and therefore more accurately describes the returned instance than the constructor.
For example Biginteger.probableprime method:

public static BigInteger probablePrime(int bitLength, Random rnd) {    if (bitLength < 2)        throw new ArithmeticException("bitLength < 2");    // The cutoff of 95 was chosen empirically for best performance    return (bitLength < SMALL_PRIME_THRESHOLD ?            smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :            largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));}


By the way also post the Largeprime method of its invocation:

private static BigInteger largePrime(int bitLength, int certainty, Random rnd) {    BigInteger p;    p = new BigInteger(bitLength, rnd).setBit(bitLength-1);    p.mag[p.mag.length-1] &= 0xfffffffe;    // Use a sieve length likely to contain the next prime number    int searchLen = (bitLength / 20) * 64;    BitSieve searchSieve = new BitSieve(p, searchLen);    BigInteger candidate = searchSieve.retrieve(p, certainty, rnd);    while ((candidate == null) || (candidate.bitLength() != bitLength)) {        p = p.add(BigInteger.valueOf(2*searchLen));        if (p.bitLength() != bitLength)            p = new BigInteger(bitLength, rnd).setBit(bitLength-1);        p.mag[p.mag.length-1] &= 0xfffffffe;        searchSieve = new BitSieve(p, searchLen);        candidate = searchSieve.retrieve(p, certainty, rnd);    }    return candidate;}

Although Smallprime and Largeprime end up returning instances through the public constructor.
But if you just use a constructor overload to express the characteristics of this instance, it's hard to remember when you should call any constructors.
and providing a name to describe the instance is more intuitive.


Advantage 2. The static factory method does not have to create a new object each time, we can control the instance.
This allows us to cache the created instances and reuse them, especially if the object is created at a higher cost.
such as boolean.valueof:

public static final Boolean TRUE = new Boolean(true);public static final Boolean FALSE = new Boolean(false);public static Boolean valueOf(boolean b) {    return (b ? TRUE : FALSE);}


Advantage 3. A static factory method can return a subtype object of the original return type.
This can reflect the flexibility of the static factory approach,
Take Enumset as an example:

/** * Creates an empty enum set with the specified element type. * * @param elementType the class object of the element type for this enum *     set * @throws NullPointerException if <tt>elementType</tt> is null */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);}


Regularenumset and Jumboenumset are subclasses of Enumset, and none of them provide a public constructor.

Advantage 4. Static factory methods are more concise when creating parameterized (generic) instances.
As an example:

public static <K, V> HashMap<K, V> newInstance() {    return new HashMap<K, V>();}


When you create an instance, you can:

Map<String,List<Integer>> n = newInstance();

Instead of

Map<String,List<Integer>> m = new HashMap<String,List<Integer>>();


It makes no sense to start from Java7, in fact Josh Bloch also mentions this in the book--java later, this type deduction is performed in constructors and method calls.


Talk about the drawbacks of the static factory approach.

    • Classes cannot be overridden if they do not contain a public or protected constructor.
      So the static factory method mentioned above can return the subtype object of the original return type. is not entirely correct.
      Although we can solve this problem through a composite approach (composition), the two classes are not is-a relationships.
    • The nature of the static factory approach is still a static method, and he does not have a particular standard.
      We cannot specifically identify a static factory method in the API documentation (perhaps by adding a standard annotation?).
      When I want to find a way to instantiate a class from the API, it is still not intuitive relative to the constructor.
      Although there is no special standard, we can make up a little bit with the standard naming.
      such as Valueof,getinstance,newinstance,newtype, etc...

Effective Java-consider replacing constructors with static factory methods

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.