Item 1: Consider static factory methods instead of constructors
Advantages:
One advantage of static factory methods is that, unlike constructors, they have names.
A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked.
A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type.(service provider framework)
A fourth advantage of static factory methods is that they reduce the ver- bosity of creating parameterized type instances.(type inference)
Disadvantages:
- The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed.
- A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.
Here are some common names for static factory methods:
valueOf—Returns an instance that has, loosely speaking, the same value as its parameters. Such static factories are effectively type-conversion methods.
of—A concise alternative to valueOf, popularized by EnumSet (Item 32).
getInstance—Returns an instance that is described by the parameters but cannot be said to have the same value. In the case of a singleton, getInstance takes no parameters and returns the sole instance.
newInstance—Like getInstance, except that newInstance guarantees that each instance returned is distinct from all others.
get_Type_—Like getInstance, but used when the factory method is in a differ- ent class. Type indicates the type of object returned by the factory method.
new_Type_—Like newInstance, but used when the factory method is in a differ- ent class. Type indicates the type of object returned by the factory method.
Item 2: Consider a builder when faced with many constructor parameters
In short, the telescoping constructor pattern works when the number of parameters is small, but it is hard to write client code when there are many parameters, and harder still to read it.
A second alternative when you are faced with many constructor parameters is the _JavaBeans _pattern, in which you call a parameterless constructor to create the object and then call setter methods to set each required parameter and each optional parameter of interest.
Unfortunately, the JavaBeans pattern has serious disadvantages of its own. Because construction is split across multiple calls, a JavaBean may be in an inconsistent state partway through its construction.
A related disadvantage is that the JavaBeans pattern pre- cludes the possibility of making a class immutable (Item 15), and requires added effort on the part of the programmer to ensure thread safety.
Luckily, there is a third alternative that combines the safety of the telescoping constructor pattern with the readability of the JavaBeans pattern. It is a form of the Builder pattern. The Builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters, especially if most of those parameters are optional.
Item 3: Enforce the singleton property with a private constructor or an enum type
A single-element enum type is the best way to implement a singleton.
Item 4: Enforce noninstantiability with a private constructor
Such_ utility classes _like _java.util
_were not designed to be instantiated: an instance would be nonsensical. A default construc- tor is generated only if a class contains no explicit constructors, so a class can be made noninstantiable by including a private constructor.
Item 5: Avoid creating unnecessary objects
An object can always be reused if it is immutable. You can often avoid creating unnecessary objects by using static factory methods in preference to constructors on immutable classes that provide both.
Because an adapter has no state beyond that of its backing object, there’s no need to create more than one instance of a given adapter to a given object.
The lesson is clear: prefer primitives to boxed primitives, and watch out for unintentional autoboxing.
Item 6: Eliminate obsolete object references
The best way to eliminate an obsolete reference is to let the variable that contained the reference fall out of scope. Generally speaking, whenever a class manages its own memory, the programmer should be alert for memory leaks. Whenever an element is freed, any object references contained in the element should be nulled out.
Because memory leaks typically do not manifest themselves as obvious failures, they may remain present in a system for years. They are typically discovered only as a result of careful code inspection or with the aid of a debugging tool known as a heap profiler. Therefore, it is very desirable to learn to anticipate problems like this before they occur and prevent them from happening.
Item 7: Avoid finalizers
One shortcoming of finalizers is that there is no guarantee they’ll be executed promptly. It can take arbitrarily long between the time that an object becomes unreachable and the time that its finalizer is executed. There is a severe performance penalty for using finalizers.
So what should you do instead of writing a finalizer for a class whose objects encapsulate resources that require termination, such as files or threads? Just provide an explicit termination method, and require clients of the class to invoke this method on each instance when it is no longer needed. Explicit termination methods are typically used in combination with try-finally construct to ensure termination.
Item 8: Obey the general contract when overriding equals
Sometimes you don’t need to override the equals
method if any of the following conditions apply:
Each instance of the class is inherently unique.
You don’t care whether the class provides a “logical equality” test.
A superclass has already overridden equals, and the superclass behavior is appropriate for this class.
The class is private or package-private, and you are certain that its equals method will never be invoked.
When you override the equals
method, you must adhere to its general contract. Here is the contract:
Reflexive: For any non-null reference value
x
,x.equals(x)
must returntrue
.Symmetric: For any non-null reference values
x
andy
,x.equals(y)
must returntrue
if and only ify.equals(x)
returnstrue
.Transitive: For any non-null reference values
x
,y
,z
, ifx.equals(y)
returnstrue
andy.equals(z)
returnstrue
, thenx.equals(z)
must returntrue
.Consistent: For any non-null reference values
x
andy
, multiple invocations ofx.equals(y)
consistently returntrue
or consistently returnfalse
, provided no information used in equals comparisons on the objects is modified.For any non-null reference value
x
,x.equals(null)
must returnfalse
.