SlideShare uma empresa Scribd logo
1 de 119
Effective Java
Joshua Bloch
Using the Java language at its best..,
Creating and
Destroying
Objects
Item 1: Consider static factory
methods instead of constructors
• A class can provide a public static factory method,
which is simply a static method that returns an
instance of the class.
• A static factory method is not the same as the
Factory Method pattern.
• One advantage of static factory methods is that,
unlike constructors, they have names, which
enables describe the object being returned.
• In a case where a class seems to require multiple
constructors with the same signature, replace the
constructors with static factory methods and
carefully chosen names to highlight their
differences.
Static Factory Methods
• 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.
• Enables immutable classes to use preconstructed
instances, or to cache instances as they’re
constructed, and dispense them repeatedly to
avoid creating unnecessary duplicate objects.
• The ability of static factory methods to return the
same object from repeated invocations allows
classes to maintain strict control over what
instances exist at any time (instance controlled).
• Instance control allows a class to guarantee that it
is a singleton or noninstantiable, ensuring immutable
class that no two equal instances exist.
Interface Based Frameworks
• A third advantage of static factory methods is that, unlike
constructors, they can return an object of any subtype of their
return type.
• An API can return objects without making their classes public is
called interface-based frameworks.
• Nearly all Java Collections Framework implementations are
exported via static factory methods in one noninstantiable class
(java.util.Collections).
• The class of the object returned by the static factory method can
vary from invocation to invocation depending on the values of
the parameters to the static factory.
• The class of the object returned by a static factory method need
not even exist at the time the class containing the method is
written, such flexible static factory methods form the basis of
service provider frameworks. E.g. JDBC.
• 3 Components of service provider framework: a service
interface, which providers implement; a provider registration API,
which the system uses to register implementations, giving clients
access to them; and a service access API, which clients use to
obtain an instance of the service.
• A service provider interface, which providers implement to create
instances of their service implementation is the optional 4th
component.
Advantage and Disadvantages
• A fourth advantage of static factory methods is that they
reduce the verbosity of creating parameterized type
instances.
• When we invoke the constructor of a parameterized
class, we must specify the type parameters.
• Map<String, List<String>> m = new HashMap<String,
List<String>>();
• With static factories, the compiler can figure out the
type parameters, known as type inference.
• 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.
Item 2: Consider a builder when faced
with many constructor parameters
• In case of large numbers of optional parameters, the
constructors or static factories do not scale well.
• Traditionally the telescoping constructor pattern I used in
such cases were only a required number of parameters
is provided to the constructor, with each optional
parameter added with a overloaded constructor.
• If the client accidentally reverses two such parameters,
the compiler won’t complain, but the program will
misbehave at runtime.
• Second alternative, the JavaBeans pattern which calls a
parameterless constructor to create the object and then
call setter methods to set each required parameter and
each optional parameter of interest.
• JavaBean may be in an inconsistent state partway
through its construction and also precludes the
possibility of making a class immutable.
Builder Pattern
• The client calls a constructor (or static factory) with all of the
required parameters (instead of creating the object directly)
and gets a builder object.
• Then the client calls setter-like methods on the builder object
to set each optional parameter of interest.
• Finally, the client calls a parameterless build method to
generate the object, which is immutable.
• The builder’s setter methods return the builder itself so that
invocations can be chained.
• A builder can impose invariants on its parameters, and is
critical that they be checked after copying the parameters
from the builder to the object, and that they be checked on
the object fields rather than the builder fields.
• A minor advantage of builders over constructors is that
builders can have multiple varargs parameters, as they use
separate methods to set each parameter.
• A single builder can be used to build multiple objects.
• Disadvantage is that in order to create an object, we must first
create its builder.
• public class NutritionFacts {
• private final int servingSize;
• private final int servings;
• private final int calories;
• private final int fat;
• public static class Builder {
• // Required parameters
• private final int servingSize;
• private final int servings;
• // Optional parameters - initialized to default values
• private int calories = 0;
• private int fat = 0;
• public Builder(int servingSize, int servings) {
• this.servingSize = servingSize;
• this.servings = servings;
• }
• public Builder calories(int val)
• { calories = val; return this; }
• public Builder fat(int val)
• { fat = val; return this; }
• public NutritionFacts build() {
• return new NutritionFacts(this);
• }
• }
• private NutritionFacts(Builder builder) {
• servingSize = builder.servingSize;
• servings = builder.servings;
• calories = builder.calories;
• fat = builder.fat;
• }
• }
Item 3: Enforce the singleton property with
a private constructor or an enum type
• A singleton is simply a class that is instantiated exactly once.
• Making a class a singleton can make it difficult to test its
clients.
• There are two ways to implement singletons.
• Both are based on keeping the constructor private and
exporting a public static member to provide access to the sole
instance.
• One approach is a final field which is initialized by the private
constructor called only once (unless using reflection to invoke
private constructor).
• Another approach is to have a public static factory method
which return the same object reference which is initialized
when class is loaded.
• It makes the singleton declarations clear and provide flexibility
to change the singleton class without API change.
• A single-element enum type is the best way to implement a
singleton
Item 4: Enforce noninstantiability
with a private constructor
• Attempting to enforce noninstantiability by making
a class abstract does not work.
• The class can be subclassed and the subclass
instantiated.
• Also it misleads the user into thinking the class was
designed for inheritance.
• A class can be made noninstantiable by including
a private constructor.
• The AssertionError isn’t strictly required in the
constructor, but it provides insurance in case the
constructor is accidentally invoked from within the
class
Item 5: Avoid creating unnecessary objects
• An object can always be reused if it is immutable.
• A string object will be reused by any other code running
in the same virtual machine that happens to contain the
same string literal.
• Static factory methods can often be used to avoid
creating unnecessary objects in preference to
constructors on immutable classes that provide both.
• With lazy initialization, it complicates the implementation
and is unlikely to result in a noticeable performance
improvement beyond what is already achieved.
• An adapter is an object that delegates to a backing
object, providing an alternative interface to the backing
object.
• 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.
Autoboxing and Reusing Objects
• Autoboxing creates unnecessary objects, hence prefer
primitives to boxed primitives, and watch out for
unintentional autoboxing.
• Creation and reclamation of small objects whose
constructors do little explicit work is cheap, especially on
modern JVMs.
• Creating additional objects to enhance the clarity,
simplicity, or power of a program is generally a good
thing.
• Avoiding object creation by maintaining your own
object pool is a bad idea unless the objects in the pool
are extremely heavyweight.
• The penalty for reusing an object when defensive
copying is called for is far greater than the penalty for
needlessly creating a duplicate object.
• Failing to make defensive copies where required can
lead to insidious bugs and security holes.
Item 6: Eliminate obsolete
object references
• An obsolete reference is simply a reference that will
never be dereferenced again.
• If an object reference is unintentionally retained, not
only is that object excluded from garbage collection.
• Such objects leads to memory leaks which cause disk
paging and even program failure with an
OutOfMemoryError
• Nulling out object references before they become
obsolete, should be the exception rather than the norm.
• The best way to eliminate an obsolete reference is to let
the variable that contained the reference fall out of
scope.
• Common sources of memory leaks are classes
managing its own memory, caches, listeners and other
callbacks.
Item 7: Avoid finalizers
• Finalizers are unpredictable, often dangerous, and
generally unnecessary.
• There is no guarantee that finalizer will be executed
promptly after an object becomes unreachable.
• Never do anything time-critical in a finalizer.
• It is possible that a program terminates without
executing finalizers on some objects that are no longer
reachable.
• Hence we should never depend on a finalizer to update
critical persistent state.
• Uncaught exceptions thrown during finalization are
ignored, which can leave objects in a corrupt state.
• There is a severe performance penalty for using finalizers,
as its about 430 times slower to create and destroy
objects with finalizers.
• Explicit termination methods (close methods) are
typically used in combination with the try-finally
construct to ensure termination.
Methods
Common to All
Objects
Item 8:
• Obey the general contract when overriding equals.
• Do not override equals method in case of following:
• Each instance of the class is inherently unique: True
for classes such as Thread.
• You don’t care whether the class provides a
“logical equality” test: java.util.Random could have
overridden equals method to check equality of two
random numbers.
• A superclass has already overridden equals, and
the superclass behavior is appropriate for this class:
Set inherits equals implementation from AbstractSet.
• The class is private or package-private, and you
are certain that its equals method will never be
invoked.
Equals overriding
• When a class has a notion of logical equality that
differs from mere object identity, and a superclass
has not already overridden equals to implement the
desired behavior.
• Generally true for Value classes such as Integer or
Date.
• Overriding equals method enables instances to
serve as map keys or set elements with predictable,
desirable behavior.
• Classes using instance control does not require
equals override. Example Enums types.
General Equals Contract
• Reflexive: x.equals(x)
• Symmetric: If x.equals(y) then y.equals(x)
• Transitive: If x.equals(y) & y.equals(z) then x.equals(z)
• Consistent: Multiple invocations of x.equals(y)
• Non-Null Reference: x.equals(null) is false.
• Never try to handle equality of super class objects with
the subclass objects in the subclass equals method. Eg:
String and CaseInsensitiveString
• There is no way to extend an instantiable class and add
a value component while preserving the equals
contract, unless you are willing to forgo the benefits of
object-oriented abstraction.
Equating Same
Implementation
• Equating objects only with same implementation
class
• @Override public boolean equals(Object o) {
• if (o == null || o.getClass() != getClass())
• return false;
• Point p = (Point) o;
• return p.x == x && p.y == y;
• }
• Violates Liskov’s subsitution principle which says that
any important property of a type should also hold
for its subtypes, so that any method written for the
type should work equally well on its subtypes.
Equals method:
Inheritence
• There is no satisfactory way to extend an
instantiable class and add a value component.
• Workaround is to Favor composition over
inheritance.
• Java.sql.Timestamp extends java.util.Date and adds
nanoseconds violating symmetry.
• One can add a value component to a subclass of
an abstract class without violating the equals
contract, as superclass instances cannot be
created directly.
• Mutable objects can be equal to different objects at different
times while immutable objects can’t.
• When you write a class, think hard about whether it should be
immutable.
• If you write immutable class, make sure that your equals
method enforces the restriction that equal objects remain
equal and unequal objects remain unequal for all time.
• Do not write an equals method that depends on unreliable
resources: java.net.URL relies on IP address.
• Non-Nullity: All objects must be unequal to null, and must
return false instead of NullPointerException.
• The equals method must first cast its argument to an
appropriate type so its accessors may be invoked or its fields
accessed.
• Before the cast, use the instanceof operator to check for type,
which also returns false if its first operand is null, regardless of
what type appears in the second operand.
• Don’t substitute another type of Object in equals declaration,
as it will not override Object.equals method but overloads it.
Guidelines for equals method
Recipe for Equals method
• Use the == operator to check if the argument is a
reference to this object.
• Use the instanceof operator to check if the
argument has the correct type. (Use of interface
refines the equals contract to permit comparisons
across classes that implement the interface.)
• Cast the argument to the correct type.
• For each “significant” field in the class, check if that
field of the argument matches the corresponding
field of this object.
Equals: Field comparsion
• If an interface access the argument fields via interface
methods, else if class access fields directly.
• For primitive types use the == operator for comparsions.
• For object reference fields invoke the equals method
recursively;
• For float and double fields use Float.compare and
Double.compare respectively due to NaN and -0.0f.
• For array fields apply above guidelines for each element.
If every element is significant use Arrays.equals methods.
• Use following idiom to compare to avoid
NullPointerException:
• (field == null ? o.field == null : field.equals(o.field)).
• Use the canonical forms for comparison for complex
fields.
• Compare the fields first which are more likely to differ and
less expensive to compare.
• Do not compare redundant fields (unless for
performance) or fields which are not part of an object’s
logical state.
Item9
• Always override hashCode when you override equals.
• If two objects are equal according to the
equals(Object) method, then calling the hashCode
method on each of the two objects must produce the
same integer result.
• It is not required that if two objects are unequal
according to the equals(Object) method, then calling
the hashCode method on each of the two objects must
produce distinct integer results.
• The hashCode method must consistently return the same
integer, provided no information used in equals
comparisons on the object is modified, unless it is
another execution of the same application.
HashCode
Implementation
• The worst implementation of hash function is
to return the same hash code for every
object, so that every object hashes to the
same bucket degenerating hash tables to
linked lists.
• A good hash function tends to produce
unequal hash codes for unequal objects.
Hash Function Recipe
• Store some constant nonzero value, in a variable.
• For each significant field:
• If the field is a boolean, compute (f ? 1 : 0).
• If the field is a byte, char, short, or int, compute (int) f.
• If the field is a long, compute (int) (f ^ (f >>> 32)).
• If the field is a float, compute Float.floatToIntBits(f).
• If the field is a double, compute Double.doubleToLongBits(f),
and then hash the resulting long.
• If field is an object reference and the class’s equals method
compares the field by recursively invoking equals, recursively
invoke hashCode on the field. Use canonical form if required.
• If value of field is null, return 0.
• If the field is an array, treat it as if each element were a
separate field.
• Compute the hash code: result = contant * result + hash_code
Hash code guidelines
• Exclude any fields that are not used in equals comparisons, or
you risk violating the second provision of the hashCode
contract, for computing hash code.
• A nonzero initial value is used in step 1 so the hash value will
be affected by initial fields whose hash value, as computed is
zero, avoiding collisions.
• The multiplication makes the result depend on the order of the
fields, yielding a much better hash function if the class has
multiple similar fields.
• If the constant value chosen were even and the multiplication
overflowed, information would be lost, as multiplication by 2 is
equivalent to shifting.
• A nice property of 31 is that the multiplication can be
replaced by a shift and a subtraction for better performance.
• If a class is immutable and the cost of computing the hash
code is significant, the hash code could be cached rather
than recalculating it each time it is requested.
• Do not be tempted to exclude significant parts of an object
from the hash code computation to improve performance.
Item 10: Always override
toString
• The toString method should return a string which is a concise
but informative representation that is easy for a person to
read.
• It is recommended that all subclasses override the toString
method.
• The toString method should return all of the interesting
information contained in the object.
• Specifying a format serves as a standard, unambiguous
representation of the object.
• Specifying a matching static factory or constructor to create
an instance of the object based on string representation is
always helpful.
• By failing to specify a format, you preserve the flexibility to add
information or improve the format in a subsequent release.
• Provide programmatic access to all of the information
contained in the value returned by toString. i.e. access to all
fields specified in toString method.
Item 11: Override clone judiciously
• The Cloneable interface was intended as a mixin
interface for objects to advertise that they permit
cloning.
• The primary flaw of the Cloneable interface is that it
lacks a clone method, and Object’s clone method is
protected.
• Cloneable determines the behavior of Object’s
protected clone implementation: if a class implements
Cloneable, Object’s clone method returns a field-by-
field copy of the object; otherwise it throws
CloneNotSupportedException.
• Cloneable modifies the behavior of a protected method
on a superclass which is atypical for interfaces.
Object Clone
• Clone creates and returns a copy of the object.
• For any Object x, the expression:
• x.clone() != x is true.
• x.clone().getClass() == x.getClass() is true.
• x.clone().equals(x) is true.
• Copying an object typically entails in creating a new instance
of its class, but it may require copying of internal data
structures as well.
• No constructors are called for cloning.
• x.clone().getClass() should be identical to x.getClass() is a
weak provision in cloning.
• The general assumption is that if in an subclass, super.clone is
invoked then the returned object will be an instance of the
subclass.
• If a clone method returns an object created by a constructor,
it will have a wrong class.
• If you override the clone method in a nonfinal class, you should
return an object obtained by invoking super.clone.
Overriding Clone method
• A class that implements Cloneable is expected to
provide a properly functioning public clone
method.
• If every field contains a primitive value or a
reference to an immutable object, the returned
object may be exactly the same without any further
processing.
• From release 1.5, it is legal for an overriding
method’s return type to be a subclass of the
overridden method’s return type i.e. covariant
return types.
• This allows the overriding method to provide more
information about the returned object and
eliminates the need for casting in the client.
Overriding Clone method
• If an object contains fields that refer to mutable objects,
using the simple clone implementation can be
disastrous.
• The reference in cloned object still points to original
instance of mutable object which changes if original
object changes.
• If the sole constructor is called such situation could never
occur.
• The clone method functions as another constructor; and
it must be ensured that it does no harm to the original
object and that it properly establishes invariants on the
clone.
• The clone architecture is incompatible with normal use
of final fields referring to mutable objects, except in
cases where the mutable objects may be safely shared
between an object and its clone. Hence final modifiers
should be removed in order to make the class clonable.
Cloning recursively insufficient
• public class HashTable implements Cloneable {
• private Entry[] buckets = ...;
• private static class Entry {
• final Object key;
• Object value;
• Entry next;
• Entry(Object key, Object value, Entry next) {
• this.key = key;
• this.value = value;
• this.next = next;
• }
• }
• // Broken - results in shared internal state!
• @Override public HashTable clone() {
• try {
• HashTable result = (HashTable) super.clone();
• result.buckets = buckets.clone(); // array references original linked
list.
• return result;
• } catch (CloneNotSupportedException e) {
• throw new AssertionError();
• }
• }
Use of Deep Copy
• public class HashTable implements Cloneable {
• private Entry[] buckets = ...;
• private static class Entry {
• ………..
• Entry(Object key, Object value, Entry next) { ………. }
• // Iteratively copy the linked list headed by this Entry
• Entry deepCopy() {
• Entry result = new Entry(key, value, next);
• for (Entry p = result; p.next != null; p = p.next)
• p.next = new Entry(p.next.key, p.next.value, p.next.next);
• return result;
• }
• }
• @Override public HashTable clone() {
• try {
• HashTable result = (HashTable) super.clone();
• result.buckets = new Entry[buckets.length];
• for (int i = 0; i < buckets.length; i++)
• if (buckets[i] != null)
• result.buckets[i] = buckets[i].deepCopy();
• return result;
• } catch (CloneNotSupportedException e) {
• throw new AssertionError();
• }
• }
Cloning complex objects
• A final approach to cloning complex objects is to
call super.clone, set all of the fields in the resulting
object to their virgin state, and then call higher-level
methods to regenerate the state of the object.
• Like a constructor, a clone method should not
invoke any nonfinal methods on the clone under
construction (Item 17).
• If clone invokes an overridden method, this method
will execute before the subclass in which it is
defined has had a chance to fix its state in the
clone, quite possibly leading to corruption in the
clone and the original.
• E.g. The put(key, value) method for cloning hash
table should be final and private.
Cloning guidelines
• Object’s clone method is declared to throw
CloneNotSupportedException, so public clone method should omit it as
methods that don’t throw checked exceptions are easier to use.
• If a class that is designed for inheritance (Item 17) overrides clone, the
overriding method should mimic the behavior of Object.clone.
• All classes that implement Cloneable should override clone with a public
method whose return type is the class itself.
• Clone method should first call super.clone and then fix any fields that
need to be fixed by copying any mutable objects that comprise the
internal “deep structure” of the object being cloned, and replacing the
clone’s references to these objects with references to the copies.
• A field representing a serial number or other unique ID or a field
representing the object’s creation time will need to be fixed, even if it is
primitive or immutable. (makes no sense to copy immutable classes.)
• A fine approach to object copying is to provide a copy constructor or
copy factory.
• A copy constructor is simply a constructor that takes a single argument
whose type is the class (or interface implemented by class) containing
the constructor.
Item12: Consider implementing
Comparable.
• The compareTo method is the sole method in the
Comparable interface.
• It is similar in character to Object’s equals method,
except that it permits order comparisons in addition
to simple equality comparisons, and it is generic.
• By implementing Comparable, a class indicates
that its instances have a natural ordering.
• If you are writing a value class with an obvious
natural ordering, such as alphabetical order,
numerical order, or chronological order, you should
strongly consider implementing the interface.
General contract of compareTo
• Compares this object with the specified object for
order.
• Returns a negative integer, zero, or a positive
integer as this object is less than, equal to, or
greater than the specified object.
• Throws ClassCastException if the specified object’s
type prevents it from being compared to this
object.
• Across classes, compareTo, unlike equals, doesn’t
have to work: it is permitted to throw
ClassCastException if two object references being
compared refer to objects of different classes.
General contract of compareTo
• If you reverse the direction of a comparison between two object
references then, if the first object is less than the second, then the
second must be greater than the first or vice versa.
• If one object is greater than a second, and the second is greater
than a third, then the first must be greater than the third.
• The final provision says that all objects that compare as equal
must yield the same results when compared to any other object.
• Similar to equals method, there is no way to extend an
instantiable class with a new value component while preserving
the compareTo contract, unless you are willing to forgo the
benefits of object-oriented abstraction.
• To add a value component to a class that implements
Comparable, don’t extend it; write an unrelated class containing
an instance of the first class and provide a “view” method that
returns its instance.
• The equality test imposed by the compareTo method should
generally return the same results as the equals method. E.g.
BigDecimal compareTo method is not consistent with equals.
Comparable implementation
• As the Comparable interface is parameterized, the
compareTo method is statically typed, there is no need
to type check or cast its argument.
• If the argument is of the wrong type, the invocation
won’t even compile.
• If the argument is null, the invocation should throw a
NullPointerException, and it will, as soon as the method
attempts to access its members.
• The field comparisons in a compareTo method are order
comparisons rather than equality comparisons.
• If a field does not implement Comparable, or you need
to use a nonstandard ordering, then explicit Comparator
can be used instead.
Guidelines for compareTo
method
• Compare integral primitive fields using the relational
operators < and >.
• For floating-point fields, use Double.compare or
Float.compare in place of the relational operators,
which do not obey the general contract for compareTo
when applied to floating point values.
• For array fields, apply these guidelines to each element.
• If a class has multiple significant fields, then you must
start with the most significant field and work your way
down the order.
• If a comparison results in anything other than zero then
return the result. If all fields are equal, then return zero.
Classes and
Interfaces
Core of Java
Item13: Minimize accessiblity of classes
and interfaces.
• The degree to which the module hides its internal data
and other implementation details from other modules
distinguishes out a well-designed module.
• Well designed module separates the API from its
implementation.
• Information hiding decouples modules, allowing isolated
development/testing and increases software reuse.
• Make each class or member as inaccessible as possible.
• Top-level (non-nested) classes and interfaces have only
two possible access levels: package-private and public.
• If any class is made public, you are obligated to support
it forever to maintain compatibility with consuming
clients.
Accessibility Class fields
• If a package-private top-level class (or interface) is used by
only one class, consider making the top-level class a private
nested class of the sole class that uses it.
• Make all members of class private first.
• Only if another class in the same package really needs to
access a member the private modifier should be removed
making it package-private.
• Both private and package-private members are part of a
class’s implementation and do not normally impact its
exported API.
• If a method overrides a superclass method, it is not permitted
to have a lower access level in the subclass than it does in the
superclass: this restricts ability to reduce accessiblity.
• It is not acceptable to make a class, interface, or member
public/protected to facilitate testing.
• Instance fields should never be public (Item 14), as you give
up the ability to limit/enforce the values that can be stored in
the field.
• Even final immutable objects loose flexibility to change
internal representation when made public.
Accessibility Static fields
• Restrict access to all static fields except for
constants, assuming that the constants form an
integral part of the abstraction provided by the
class.
• A nonzero-length array is always mutable, so it is
wrong for a class to have a public static final array
field, or an accessor that returns such a field.
• public static final Thing[] VALUES = { ... };
Item 14: In public classes, use accessor
methods, not public fields
• If a class is accessible outside its package, provide
accessor methods, to preserve the flexibility to
change the class’s internal representation.
• If a class is package-private or is a private nested
class, there is nothing inherently wrong with
exposing its data fields. (generates less visual
clutter)
• Public classes should never expose mutable fields
and should avoid exposing immutable fields too.
Item 15: Minimize mutability
• An immutable class is simply a class whose instances
cannot be modified.
• Immutable classes are easier to design and implement,
less prone to errors and are more secure.
• The functional approach is the one in which the
methods return the result of applying the operation
without modifying the state of the object.
• Immutable objects are simple and are inherently thread-
safe; as they do not require synchronization.
• Immutable objects can be shared freely.
• They can be reused by providing static factories that
cache frequently requested instances to avoid creating
new instances when existing ones would do.
5 Rule for Immutable Class
• Don’t provide any methods that modify the object’s
state (i.e. mutators).
• Ensure that the class can’t be extended. (final class)
• Make all fields final.
• Make all fields private. (change internal structure)
• Ensure exclusive access to any mutable
components. If class has any fields that refer to
mutable objects, ensure that clients of the class
cannot obtain references to these objects. Never
initialize such a field to a client-provided object
• reference or return the object reference from an
accessor.
Immutable Objects
• Not only immutable objects can be shared, but their
internals can be shared too.
• Immutable objects make great building blocks for other
objects, whether mutable or immutable.
• Immutable objects make great map keys and set
elements as their values will not be changing.
• The only real disadvantage of immutable classes is that
they require a separate object for each distinct value.
• If the immutable class implements Serializable and it
contains one or more fields that refer to mutable
objects, then you must provide an explicit readObject or
readResolve method, or use the
ObjectOutputStream.writeUnshared and
ObjectInputStream.readUnshared methods, even if the
default serialized form is acceptable.
Immutable Object: Performance
• The performance problem is magnified if a multistep
operation is performed that generates a new
object at every step, eventually discarding all
objects except the final result.
• In such case, first try to guess which multistep
operations will be commonly required and provide
them as primitives.
• The package-private mutable companion class for
the immutable class enables to overcome
performance problems, if we can accurately
predict which complex multistage operations clients
will want to perform on the immutable class.
• Examples: StringBuilder (String), BitSet (BigInteger).
Design Alternatives
• In order to guarantee immutability the class must be
declared as final.
• An alternative approach is to make all of its constructors
private or package-private, and to add public static
factories in place of the public constructors (Item 1).
• It is a better approach as for the clients of immutable
class that reside outside its package, the immutable
class is effectively final because it is impossible to extend
a class that comes from another package and that
lacks a public or protected constructor.
• Also it provides flexibility for multiple implementation
classes.
Avoid externally visible
change
• As stated before for Immutable classes no methods
may modify the object and that all its fields must be
final.
• In truth, no method may produce an externally
visible change in the object’s state.
• Some immutable classes have one or more nonfinal
fields in which they cache the results of expensive
computations the first time they are needed.
• If the same value is requested again, the cached
value is returned, saving the cost of recalculation.
• Such technique is called lazy initialization. (used in
String)
Immutable Guidelines
• Classes should be immutable unless there’s a very good
reason to make them mutable.
• Resist the urge to write a set method for every get
method.
• Prefer making large value objects such as BigInteger and
String as immutable.
• If a class cannot be made immutable, limit its mutability
as much as possible.
• Try to make every field final unless there is a compelling
reason to make it nonfinal. (reducing number of states).
• Don’t provide a public initialization method separate
from the constructor or static factory unless there is a
compelling reason to do so.
• Don’t provide a “reinitialize” method that enables an
object to be reused as if it had been constructed with a
different initial state.
Item 16: Favor composition
over inheritance
• It is safe to use inheritance within a package, where
the subclass and the superclass implementations
are under the control of the same programmers.
• It is also safe to use inheritance when extending
classes specifically designed and documented for
extension (Item 17).
• Inheriting from ordinary concrete classes across
package boundaries, however, is dangerous.
• Unlike method invocation, inheritance violates
encapsulation.
Dependency in Inheritence
• In inheritance, a subclass depends on the
implementation details of its superclass for its proper
function.
• If the superclass’s implementation changes after a
release, the subclass may break, even though its code is
untouched.
• Hence a subclass must evolve in tandem with its
superclass, unless the superclass’s authors have
designed and documented it specifically for the
purpose of being extended.
• E.g. Internally, HashSet’s addAll method is implemented
on top of its add method.
• Reimplementing superclass methods for self-use is
difficult, time-consuming, error-prone and not always
possible as some methods require access to superclass
private fields which are inaccessible to the subclass
Fragility in Subclasses
• A related cause of fragility in subclasses is that their
superclass can acquire new methods in subsequent
releases.
• Securing all the methods (by overriding) for an operation
to satisfy a predicate may not work if a new method
capable of doing the same operation is added in
superclass.
• Even if we don’t override existing methods and try to
add new methods in subclass, the superclass can
acquire a new method in a subsequent release which
has the same signature but a different return type than
the method in subclass, causing subclass method to no
longer compile.
• If you’ve given the subclass a method with the same
signature and return type as the new superclass method,
then you’re now overriding it.
Alternative: Composition
• Instead of extending an existing class, use
composition to give the new class a private field
that references an instance of the existing class.
• In composition design the existing class becomes a
component of the new one.
• Each instance method in the new class invokes the
corresponding method on the contained instance
of the existing class and returns the results, known as
forwarding, and the methods in the new class are
known as forwarding methods.
• The resulting class will have no dependencies on
the implementation details of the existing class.
• Even adding new methods to the existing class will
have no impact on the new class.
Wrapper Classes
• Unlike the inheritance-based approach, which
works only for a single concrete class and requires a
separate constructor for each supported
constructor in the superclass, the wrapper class can
be used with any Superclass implementation and
will work in conjunction with any preexisting
constructor.
• Wrapper classes fall in the Decorator pattern as they
decorate the superclass by adding functionality.
• When the wrapper object passes itself to the
wrapped object then only it is a delegation.
Wrapper class and
Forwarding methods
• Wrapper classes are not suitable for callback
frameworks as a wrapped object doesn’t know
about its wrapper, and it passes a reference to itself
(this) which the callbacks elude as the wrapper
(SELF Problem).
• It is tedious to write forwarding methods, but we
can write the forwarding class for each interface
only once (in the package of the interface).
When to use Inheritance
• Inheritance is appropriate only in circumstances where the
subclass really is a subtype of the superclass (“is-a”
relationship exists between the two classes).
• Before extending class A by class B, as the question: Is every
Class B really an Class A ?
• If A is not an essential part of B, merely a detail of its
implementation then use composition.
• E.g. of violations: Stack extending Vector, Properties extending
HashTable.
• If used inheritance where composition is appropriate,
unnecessary implementation details are exposed.
• The resulting API ties to the original implementation, forever
limiting the performance of subclass, leads to confusing
semantics and enables the client to corrupt invariants of the
subclass by modifying the superclass directly.
• Does the class you contemplate to extend have any flaws in
its API ?
• Are you comfortable propograting those flaws into your class ?
Item 17: Design and document for inheritance or else prohibit it
• The class must document precisely the effects of overriding any
method (i.e. self-use of overridable methods).
• For each public or protected method or constructor, the
documentation must indicate which overridable methods the
method or constructor invokes, in what sequence, and how the
results of each invocation affect subsequent processing.
• A class must document any circumstances under which it might
invoke an overridable method.
• By convention, a method that invokes overridable methods
contains a description of these invocations at the end of its
documentation comment.
• This violates the rule that good API documentation should
describe what a given method does and not how it does it? (as
Inheritance violates Encpsulation)
• To document a class so that it can be safely subclassed, you must
describe implementation details that should otherwise be left
unspecified.
• A class may have to provide hooks into its internal workings in the
form of judiciously chosen protected methods or, in rare
instances, protected fields.
• E.g. The removeRange method from java.util.AbstractList is
provided solely to make it easy for subclasses to provide a fast
clear method on sublists.
Overriding Methods
• A class should expose as few protected members as possible, because
each one represents a commitment to an implementation detail.
• On the other hand, should not expose too few, as a missing protected
member can render a class practically unusable for inheritance.
• The only way to test a class designed for inheritance is to write
subclasses.
• Constructors must not invoke overridable methods, directly or indirectly.
• The overriding method in the subclass will get invoked before the subclass
constructor has run.
• Avoid a class designed for inheritance implement Clonable or
Serializable.
• Neither clone nor readObject may invoke an overridable method,
directly or indirectly. (failure can damage original object)
• A class having the readResolve or writeReplace methods should be
made protected rather than private.
• To avoid subclassing related bugs, prohibit subclassing in classes that are
not designed and documented to be safely subclassed. (use final or
make constructors private and use public static factories)
• If inheritance must be allowed for the class, ensure that the class never
invokes any of its overridable methods and to document this fact.
Item 18: Prefer interfaces to
abstract classes
• Basic difference is that abstract classes are permitted to
contain implementations for some methods while interfaces
are not.
• Existing classes can be easily retrofitted to implement a new
interface. (just add required methods and implements clause)
• On other hand, existing classes cannot, in general, be
retrofitted to extend a new abstract class.
• In order to have two classes extending the same abstract
class, the abstract class should be placed high up in the type
hierarchy where it subclasses an ancestor of both the classes.
• Interfaces are ideal for defining mixins.
• A mixin is a type that a class can implement in addition to its
“primary type” to declare that it provides some optional
behavior. E.g. Comparable interface.
• Mixin interface allows the optional functionality to be “mixed
in” to the type’s primary functionality.
Pros of Interfaces
• Interfaces allow the construction of nonhierarchical type
frameworks.
• E.g. Singer and Songwriter interface can be implemented
together.
• The alternative is a bloated class hierarchy containing a
separate class for every supported combination of attributes.
• If there are n attributes in the type system, then there are 2n
possible combinations that might need to be supported (a
combinatorial explosion).
• Bloated class hierarchies can lead to bloated classes
containing many methods that differ only in the type of their
arguments, as there are no types in the class hierarchy to
capture common behaviors.
• Interfaces enable safe, powerful functionality enhancements
via the wrapper class idiom,
• If you use abstract classes to define types, no alternative for
composition but to use inheritance .
Skeletal Implementation
• Using interfaces to define types does not prevent us
from providing abstract implementations.
• One can combine the virtues of interfaces and
abstract classes by providing an abstract skeletal
implementation class to go with each nontrivial
interface that is exported.
• The skeletal implementation does the task of
implementing the interface.
• Skeletal implementations are called
AbstractInterface, such as AbstractCollection,
AbstractSet etc.
• Skeletal implementations can be easily extended
with a concrete implementation and exposed as
an Adapter using static factories.
Skeletal Implementation
• The skeletal implementations provide the
implementation assistance of abstract classes without
imposing the severe constraints which abstract classes
impose when they serve as type definitions.
• Extending Skeletal Implementation is a choice, but is
strictly optional (as interface can be implemented
directly).
• The class implementing the interface can forward
invocations of interface methods to a contained
instance of a private inner class that extends the skeletal
implementation (known as simulated multiple
inheritance).
• To write skeletal implementations, first study the interface
deciding the primitive (abstract) methods and provide
concrete implementations for all the other methods.
Simple Implementation and
Interface disadvantages
• A simple implementation is similar to skeletal
implementation which implements an interface and is
designed for inheritance, but it differs in that it isn’t
abstract: it is the simplest possible working
implementation.
• Using abstract classes to define types has one
advantage over interface: It is far easier to evolve an
abstract class than an interface.
• If, in a subsequent release, we want to add a new
method to an abstract class, it is always possible to add
a concrete method containing a reasonable default
implementation.
• Once an interface is released and widely implemented,
it is almost impossible to change.
• When ease of evolution is deemed more important than
flexibility and power then abstract classes are preferred
over interfaces to define a type.
Item 19: Use interfaces only to define types
• When a class implements an interface, the interface serves as
a type that can be used to refer to instances of the class.
• Constant interface on other hand contains no methods but
solely static final fields, each exporting a constant.
• The constant interface pattern is a poor use of interfaces.
• Implementing a constant interface causes the
implementation detail of using constants to leak into the
class’s exported API.
• Constant interface creates confusion among clients, adds
worse commitments (as in future the constants might not be
used by the class still implementing interface to ensure binary
compatibility).
• If a nonfinal class implements a constant interface, all of its
subclasses will have their namespaces polluted by the
constants in the interface. E.g. java.io.ObjectStreamConstants
• If the constants are strongly tied to an existing class or
interface, you should add them to the class or interface.
• If the constants are best viewed as members of an
enumerated type, they should export them as an enum type
or with a noninstantiable utility class.
Item 20: Prefer class hierarchies to tagged classes
• A class whose instances come in two or more flavors and
contain a tag field indicating the flavor of the instance is
called a tagged class.
• These classes are cluttered with boilerplate, including enum
declarations, tag fields, and switch statements.
• Readability is further harmed and Memory footprint is
increased (due to irrelevant fields of other flavors).
• Fields can’t be made final unless constructors initialize
irrelevant fields, resulting in more boilerplate.
• Constructors must set the tag field and initialize the right data
fields without any compiler help.
• To add a new flavor to a tagged class the source file needs to
be modified.
• The data type of an instance gives no clue as to its flavor.
• To transform tagged class to class hierarchy, define an
abstract class containing abstract methods which depend on
tag value and add common methods independent of the tag
value.
• Define a concrete subclass of the root class for each flavor of
the original tagged class containing data fields for its flavor.
Item 21: Use function objects to represent strategies
• Function pointer, delegates allow programs to store and
transmit the ability to invoke a particular function.
• They are used to allow the caller of a function to specialize its
behavior by passing in a second function.
• Invoking a method on an object typically performs some
operation on that object.
• Function objects are the objects whose methods perform
operations on other objects, passed explicitly to the methods.
• The strategy interface represents the strategy to use function
objects. E.g. Comparator interface (with compareTo method)
• The concrete strategy classes implement strategy interface.
• They are stateless (no fields), preferred to be singleton
• When a concrete strategy is used only once, it is typically
declared and instantiated as an anonymous class.
• When a concrete strategy is designed for repeated use, it is
generally implemented as a private static member class and
exported in a public static final field whose type is the strategy
interface.
Item 22: Favor static member classes
over nonstatic
• A nested class should exist only to serve its enclosing class.
• There are four kinds of nested classes:
• static member classes, nonstatic member classes, anonymous
classes, and local classes.
• A static member class is as a public helper class, useful only in
conjunction with its outer class.
• An instance of a nonstatic member class is implicitly
associated with an enclosing instance of its containing class.
• One can invoke methods on the enclosing instance or obtain
a reference to the enclosing instance using the qualified this
construct.
• It is impossible to create an instance of a nonstatic member
class without an enclosing instance.
• Association between nonstatic member class instance and its
enclosing instance is established automatically when the
former is created and cannot be modified.
Non-Static Member Class
• Nonstatic member class is used to define an Adapter
that allows an instance of the outer class to be viewed
as an instance of some unrelated class.
• E.g. Map has nonstatic member implementing collection
views which are returned by Map’s keySet, entrySet.
• If you declare a member class that does not require
access to an enclosing instance, always put the static
modifier in its declaration.
• Storing an extraneous reference to enclosing instance
costs time and space, and avoids been garbage
collected.
• A common use of private static member classes is to
represent components of the object represented by
their enclosing class. E.g. Map and Entry
Anonymous Class
• An anonymous class is not a member of its enclosing
class and cannot have any static members.
• They are simultaneously declared and instantiated at
the point of use.
• Limitations are cannot instantiate except at the point of
declaration and cannot use instanceof tests.
• Common use of anonymous classes is to create function
objects or process objects on the fly.
• If we need to create instances from only one location
and there is a preexisting type that characterizes the
class, make it an anonymous class; otherwise, make it a
local class.
Generics
Casting gets automated.
Item 23: Don’t use raw types
in new code
• A class or interface whose declaration has one or
more type parameters is a generic class or
interface.
• List interface has a single type parameter, E,
representing the element type of the list.
• Generic classes and interfaces are collectively
known as generic types.
• List<String> is a parameterized type representing a
list whose elements are of type String. (String is the
actual type parameter corresponding to the formal
type parameter E.)
• Each generic type defines a raw type (without any
accompanying actual type parameters)
Advantages of Generics
• Using generics, an erroneous insertion in collections
generates a compile-time error message that tells
exactly what is wrong.
• Added benefit is we no longer have to cast
manually when removing elements from collections
as compiler inserts invisible casts for us.
• It is still legal to use collection types and other
generic types without supplying type parameters,
but should be avoided.
• If you use raw types, you lose all the safety and
expressiveness benefits of generics.
Prefer Object parameterized type
over raw type
• It is fine to use types that are parameterized to allow
insertion of arbitrary objects, such as List<Object>.
• The raw type List opts out generic type checking, while
List<Object> explicitly tells the compiler that it is capable
of holding objects of any type.
• Set<Object> is a parameterized type representing a set
that can contain objects of any type.
• While we can pass a List<String> to a parameter of type
List, we can’t pass it to a parameter of type
List<Object>.
• List<String> is a subtype of the raw type List, but not of
the parameterized type List<Object>.
• We lose type safety if you use a raw type like List, but not
if we use a parameterized type like List<Object>.
Unbounded Wildcard Types
• In case we want to write a method that takes two sets
and returns the number of elements they have in
common.
• Instead of using raw types use unbounded wildcard
types.
• If we want to use a generic type but you don’t know or
care what the actual type parameter is, we can use a
question mark instead.
• E.g. The unbounded wildcard type for the generic type
Set<E> is Set<?>.
• Set<?> is a wildcard type representing a set that can
contain only objects of some unknown type.
• We cannot put any element (other than null) into a
Collection<?> and cannot assume anything about the
type of the objects that we get out.
Exceptions for using Raw Types
• Two minor exceptions for not using raw types:
• Raw types must be used in class literals.
• E.g. List.class, String[].class, and int.class are all legal,
but List<String>.class and List<?>.class are not legal.
• As generic type information is erased at runtime, it is
illegal to use the instanceof operator on
parameterized types other than unbounded
wildcard types.
• if (o instanceof Set) { // Raw type
• Set<?> m = (Set<?>) o; // Wildcard type
• }
Item 24: Eliminate unchecked
warnings
• Eliminate every unchecked warning that you can.
• If you can eliminate all warnings, you are assured that your
code is typesafe.
• Every unchecked warning represents the potential for a
ClassCastException at runtime.
• If you can’t eliminate a warning, and you can prove that the
code that provoked the warning is typesafe, then (and only
then) suppress the warning with an
@SuppressWarnings("unchecked") annotation.
• The SuppressWarnings annotation can be used at any
granularity, from an individual local variable declaration to an
entire class.
• Always use the SuppressWarnings annotation on the smallest
scope possible.
• It is illegal to put a SuppressWarnings annotation on the return
statement, because it isn’t a declaration.
• Every time you use an @SuppressWarnings("unchecked")
annotation, add a comment saying why it’s safe to do so.
Item 25: Prefer lists to arrays
• Arrays are covariant i.e. if Sub is a subtype of Super, then
the array type Sub[] is a subtype of Super[].
• Generics, by contrast, are invariant, i.e. for any two
distinct types Type1 and Type2, List<Type1> is neither a
subtype nor a supertype of List<Type2>.
• // Fails at runtime!
• Object[] objectArray = new Long[1];
• objectArray[0] = "I don't fit in"; // Throws
ArrayStoreException
• // Won't compile!
• List<Object> ol = new ArrayList<Long>(); // Incompatible
types
• ol.add("I don't fit in");
Arrays and Generics
• With generics we find out incompatible type errors at
compile time compared to arrays.
• Arrays are reified i.e. arrays know and enforce their
element types at runtime.
• Generics, by contrast, are implemented by erasure, i.e.
they enforce their type constraints only at compile time
and discard (or erase) their element type information at
runtime.
• Erasure is allows generic types to interoperate freely with
legacy code that does not use generics.
• Due to such differences, arrays and generics do not mix
well.
• It is illegal to create an array of a generic type, a
parameterized type, or a type parameter (as it isn’t
typesafe) . E.g. List<E>[], new List<String>[], new E[] gives
compile time error.
Why generic array creation is
illegal
• List<String>[] stringLists = new List<String>[1]; // (1)
• List<Integer> intList = Arrays.asList(42); // (2)
• Object[] objects = stringLists; // (3)
• objects[0] = intList; // (4)
• String s = stringLists[0].get(0); // (5)
• Line 3 stores the List<String> array into an Object array
variable, which is legal because arrays are covariant.
• Line 4 stores the List<Integer> into the sole element of the
Object array, which succeeds because the runtime type
of a List<Integer> instance is simply List, and the runtime
type of a List<String>[] instance is List[], so this assignment
doesn’t generate an ArrayStoreException.
NonReifiable Types
• Types such as E, List<E>, and List<String> are technically
known as nonreifiable types.
• A non-reifiable type is one whose runtime representation
contains less information than its compile-time
representation.
• Unbounded wildcard types such as List<?> and
Map<?,?> are the only parameterized types that are
reifiable.
• It is legal, to create arrays of unbounded wildcard types.
• As generic array creation is prohibited, it is not generally
possible for a generic type to return an array of its
element type.
• Also if the element type of an varargs array is not
reifiable, we get a warning.
• The best solution is often to use the collection type
List<E> in preference to the array type E[], sacrificing
some performance or conciseness in exchange for
better type safety and interoperability.
Casting using nonreifiable types
• static void someMethod(List<E> list) {
• E[] snapshot = (E[]) list.toArray(); // gives warning
• }
• The compiler can’t check the safety of the cast at
runtime because it doesn’t know what E is at runtime (as
element type information is erased from generics at
runtime).
• The compiletime type of snapshot is E[] which could be
String[], Integer[], or any other kind of array, while the
runtime type is Object[].
• Casts to arrays of non-reifiable types should be used only
under special circumstances (Item 26).
• Summary: Arrays are covariant and reified; generics are
invariant and erased. Hence arrays provide runtime type
safety but not compile-time type safety and vice versa
for generics.
Item 26: Favor generic types
• Prefer generification of the class.
• The first step in generifying a class is to add one or more
type parameters to its declaration.
• The conventional name of such type parameter is E.
• The next step is to replace all the uses of the type Object
with the appropriate type parameter, and then try to
compile the resulting program.
• The common compilation error when we write a generic
type that is backed by an array is that we can’t create
an array of a non-reifiable type (i.e. E).
• E[] elements = new E[DEFAULT_CAPACITY];
• First solution is to create an array of Object and cast it to
the generic array type.
• E[] elements = (E[]) new Object [DEFAULT_CAPACITY];
• Suppress the warning if the array is private and never
passed outside to any other methods, and only elements
stored in array are of type E.
Can’t create an array of a
non-reifiable type
• Second solution is to change the type of the field
elements from E[] to Object[] and cast every
element retrieved from the array, from Object to E.
• Object[] elements = new Object
[DEFAULT_CAPACITY];
• E result = (E) elements [--size];
• It is riskier to suppress an unchecked cast to an
array type than to a scalar type, suggesting the
second solution as better solution.
• But second solution requires casts to E for every
read operation compared to single cast to E[].
Bounded type parameter
• It is not always possible or desirable to use lists inside the generic
types instead of arrays.
• Java doesn’t support lists natively, so some generic types, such as
ArrayList, must be implemented atop arrays.
• We cannot create a Class object of primitive type, i.e. Stack<int>,
as it results in compile time error (instead use boxed primitive
types).
• class DelayQueue<E extends Delayed> implements
BlockingQueue<E>;
• The type parameter list (<E extends Delayed>) requires that the
actual type parameter E must be a subtype of
java.util.concurrent.Delayed.
• It allows the DelayQueue implementation and its clients to take
advantage of Delayed methods on the elements of a
DelayQueue, without the need for explicit casting or the risk of a
ClassCastException.
• The type parameter E is known as a bounded type parameter.
• Note that the subtype relation is defined so that every type is a
subtype of itself, hence it is legal to create a
DelayQueue<Delayed>.
Item 27: Favor generic methods
• Static utility methods are particularly good
candidates for generification.
• To make the method typesafe, modify the method
declaration to declare a type parameter
representing the element type <E> for the
arguments and the return value and use the type
parameter in the method.
• The type parameter list <E>, which declares the
type parameter, goes between the method’s
modifiers and its return type (i.e. Set<E>).
• One restriction is that all the method parameters
and return value type has to be of the same type.
Type Inference
• We don’t need to specify the value of the type
parameter explicitly for generic methods as we must
when invoking generic constructors.
• The compiler figures out the value of the type
parameters by examining the types of the method
arguments.
• The compiler sees that both arguments if of type e.g.
String, and hence know that type parameter E must be
String. Such process is called Type Inference.
• Type inference can be used to ease the process of
creating parameterized type instances.
• public static <K,V> HashMap<K,V> newHashMap() {
• return new HashMap<K,V>();
• }
• Map<String, List<String>> anagrams = newHashMap();
Generic Singleton Pattern
• We need to create an object that is immutable but applicable to many
different types occasionally.
• Because generics are implemented by erasure (Item 25), we can use a
single object for all required type parameterizations.
• Although we do need to write a static factory method to repeatedly dole
out the object for each requested type parameterization.
• Such pattern is used in function objects such as Collections.reverseOrder.
• // Generic singleton factory pattern
• private static UnaryFunction<Object> IDENTITY_FUNCTION =
• new UnaryFunction<Object>() {
• public Object apply(Object arg) { return arg; }
• };
• // IDENTITY_FUNCTION is stateless (returns arg unmodified) and its type
parameter is unbounded so it's safe to share one instance across all types.
• @SuppressWarnings("unchecked")
• public static <T> UnaryFunction<T> identityFunction() {
• return (UnaryFunction<T>) IDENTITY_FUNCTION;
• }
Recursive Type Bound
• It is permissible for a type parameter to be bounded
by some expression involving that type parameter
itself known as a recursive type bound.
• The most common use of recursive type bounds is in
connection with the Comparable interface which
defines natural ordering.
• The type parameter T defines the type to which
elements of the type implementing Comparable<T>
can be compared.
• Nearly, all types can be compared only to elements
of their own type. String implements Comparable<String>
• // Using a recursive type bound to express mutual
comparability
• public static <T extends Comparable<T>> T
max(List<T> list) {...}
Item 28: Use bounded wildcards to
increase API flexibility
• Parameterized types are invariant i.e. for any two
distinct types Type1 and Type2, List<Type1> is
neither a subtype nor a supertype of List<Type2>.
• More flexibility is needed than invariant typing can
provide.
• E.g. Suppose we have a Stack<Number> and if we
invoke push(intVal), where intVal is of type Integer,
even Integer is subtype of Number it gives error
message.
• public void pushAll(Iterable<E> src) {
• for (E e : src) { push(e); }
• }
Bounded Wildcard Type
• The type of the input parameter to pushAll can be
changed from “Iterable of E” to “Iterable of some
subtype of E” using the wildcard type : Iterable<?
extends E>.
• Similarly, if we have a Stack<Number> and a variable of
type Object, and if we try to pop an element from the
stack and store in the variable, it fails (even though
Object is subtype of Number).
• public void popAll(Collection<E> dst) {
• while (!isEmpty()) { dst.add(pop()); }
• }
• The type of input parameter to popAll can be changed
from “collection of E” to “collection of some supertype
of E” using rhe wildcard type: Collection<? super E>.
producer-extends : consumer-super
• For maximum flexibility, use wildcard types on input
parameters that represent producers or consumers.
• If an input parameter is both a producer and a
consumer, then wildcard types will do no good: you
need an exact type match i.e. without any wildcards.
• PECS stands for producer-extends, consumer-super.
• If a parameterized type represents a T producer, use <?
extends T>; if it represents a T consumer, use <? super T>.
• Do not use wildcard types as return types.
• Rather than providing additional flexibility for your users,
wildcard on return types forces them to use wildcard
types in client code.
• If the user of a class has to think about wildcard types,
there is probably something wrong with the class’s API.
Explicit Type Parameter
• If the compiler doesn’t infer the type that you wish it
had, you can tell it what type to use with an explicit
type parameter.
• Set<Number> numbers =
Union.<Number>union(integers, doubles);
• Comparables are always consumers, so we should
always use Comparable<? super T> in preference to
Comparable<T>.
• Similarly we should always use Comparator<? super
T> in preference to Comparator<T>.
• This allows us to apply the methods declared to
Collections<E> even though its element type E does
not implement Comparable<E>, but is a
subinterface S which extends Comparable<S>.
Common Errors
• In case of below incompatible type:
• public static <T extends Comparable<? super T>> T
max(List<? extends T> list) {
• Iterator<T> i = list.iterator();
• }
• Means that list is not a List<T>, so its iterator method
doesn’t return Iterator<T>.
• It returns an iterator of some subtype of T, so we replace
the iterator declaration which uses a bounded wildcard
type:
• Iterator<? extends T> i = list.iterator();
Dual Declarations
• Dual declarations are possible with one using
unbounded type parameter while the other using an
unbounded wildcard.
• public static <E> void swap(List<E> list, int i, int j);
• public static void swap(List<?> list, int i, int j);
• If a type parameter appears only once in a method
declaration, replace it with a wildcard.
• If unbounded replace by unbounded wildcard; if
bounded replace by bounded wildcard type parameter.
• Private generic helper methods to capture wildcard
type need to be added to avoid issues (e.g. we cannot
put any value except null into a List<?> as we can get
any value out).
Item 29: Consider typesafe
heterogeneous containers
• In all use of generics the container is parameterized,
and limits to a fixed number of type parameters per
container.
• In a case were database row with many columns
should all be accessible in a typesafe manner,
parameterizing the key instead of the container is
helpful.
• In such approach, we present the parameterized
key to the container to insert or retrieve a value.
• The generic type system is used to guarantee that
the type of the value agrees with its key.
Typesafe heterogeneous Container
• The Class object plays the part of the parameterized key
as the class Class was generified in release 1.5.
• The type of a class literal is no longer simply Class, but
Class<T>. E.g. String.class is of type Class<String>.
• When a class literal is passed among methods to
communicate both compile-time and runtime type
information, it is called a type token.
• E.g. Below is the Favorite class API:
• public class Favorites {
• public <T> void putFavorite(Class<T> type, T instance);
• public <T> T getFavorite(Class<T> type);
• }
• A Favorites instance is typesafe: it will never return an
Integer when you ask it for a String; and heterogeneous:
unlike an ordinary map, all the keys are of different
types.
Favorite Class Example
• Each Favorites instance is backed by a private
Map<Class<?>, Object>.
• The wildcard type is nested i.e. it’s not the type of the
Map that’s a wildcard type but the type of its key.
Hence every key can have a different parameterized
type.
• The Map does not guarantee the type relationship
between keys and values, which is that every value is of
the type represented by its key.
• A dynamic cast is used to cast the object reference to
the type represented by the Class object, using Class’s
cast method in the get implementation.
• The cast method simply checks that its argument is an
instance of the type represented by the Class object. If
so, then returns the argument, else throws a
ClassCastException.
Casting and Bounded Type
• The signature of the cast method takes full advantage of
the fact that class Class has been generified, with its
return type being the type parameter if the Class object.
• public class Class<T> { T cast(Object obj); }
• An instanceof check can be used to ensure that the put
impementation never violates its type invariant. Also
used by checkedlist, checkedset etc.
• Favorite Class cannot be used on a non-reifiable type.
i.e. String or String[] can be stored but not List<String>.
• The type tokens used by Favorites can be bounded
simply by a type token that places a bound on what
type can be represented, using a bounded type
parameter or a bounded wildcard.
The asSubclass Method
• Suppose we have an object of type Class<?> and
we want to pass it to a method that requires a
bounded type token such as Class<T>
annotationType.
• We could cast the object to Class<? extends
Annotation>, but this cast is unchecked, so it would
generate a compile-time warning.
• class Class provides an instance method called
asSubclass that performs such cast safely.
• The asSubclass method casts the Class object on
which it’s called to represent a subclass of the class
represented by its argument.
• If the cast succeeds, the method returns its
argument; if it fails, it throws a ClassCastException.
Enums and
Annotations
Item 30: Use enums instead of int
constants
• An enumerated type is a type whose legal values consist of a
fixed set of constants, such as the seasons of the year.
• Int enum pattern is a common pattern to declare a group of
named int constants, one for each member of the type.
• Int enum pattern are compile-time-constants and required to be
recompiled when changed.
• There is no easy way to translate int enum constants into printable
strings.
• There is no reliable way to iterate over all the int enum constants
in a group, or even to obtain the size of an int enum group.
• The variant of int enum pattern were String constants are used in
place of int constants is known as the String enum pattern.
• As it relies on string comparisons it faces performance problems.
• Java’s enum types are classes that export one instance for each
enumeration constant via a public static final field.
• Enum types are effectively final, by virtue of having no accessible
constructors, hence having no instances but only enum
constants.
Benefits of Enum Types
• Enums provide compile-time type safety, as attempts to
pass values of the wrong type will result in compile-time
errors, as will attempts to assign an expression of one
enum type to a variable of another, or to use the ==
operator to compare values of different enum types.
• Enum types with identically named constants coexist
peacefully as each type has its own namespace.
• We can add or reorder constants in an enum type
without recompiling its clients because the fields that
export the constants provide a layer of insulation
between an enum type and its clients.
• Also enum types let us add arbitrary methods and fields
and implement arbitrary interfaces.
Methods in Enum Types
• Methods in enum types enable to associate data
with its constants.
• E.g. Planet types has a mass and a radius from
which surface gravity can be computed which in
turns enables to calculate mass of object on the
planet.
• public enum Planet {
• MERCURY(3.302e+23, 2.439e6),
• VENUS (4.869e+24, 6.052e6), …………….
• }
• The numbers in parentheses after each enum
constant are parameters that are passed to its
constructor.
More on enum methods
• To associate data with enum constants, declare
instance fields and write a constructor that takes the
data and stores it in the fields.
• Enums are by their nature immutable, so all fields
should be final and preferably private.
• Enums can have static methods such as values
method that returns an array of its values in the
order they were declared, or toString method that
returns the declared name of each enum value.
• Java’s printf method uses %n where you’d use n.
• If an enum is generally useful, it should be a top-
level class; if its use is tied to a specific top-level
class, it should be a member class of that top-level
class.
Constant-specific method
implementations
• Sometimes we need to associate fundamentally different
behavior with each constant, e.g. an enum type representing
operations on a basic four-function calculator, with a method
to perform the arithmetic operation represented by each
constant (usually handled by switch statement).
• The code is fragile as we add a new enum constant but may
forget to add a corresponding case to the switch, compiling
but failing at runtime.
• Declare an abstract (e.g. apply) method in the enum type,
and override it with a concrete method for each constant in a
constant-specific class body.
• Such methods are knows as constant-specific method
implementations.
• As abstract methods in an enum type must be overridden with
concrete methods in all of its constants, compiler gives error if
method is not implemented.
• Constant-specific method implementations can be combined
with constant specific data.
Constant specific class
• public enum Operation {
• PLUS("+") {
• double apply(double x, double y) { return x + y; }
• },
• MINUS("-") {
• double apply(double x, double y) { return x - y; }
• },
• TIMES("*") {
• double apply(double x, double y) { return x * y; }
• },
• DIVIDE("/") {
• double apply(double x, double y) { return x / y; }
• };
•
• private final String symbol;
• Operation(String symbol) { this.symbol = symbol; }
• @Override public String toString() { return symbol; }
•
• abstract double apply(double x, double y);
• }
Enum constant methods
• Enum types have an automatically generated
valueOf(String) method that translates a constant’s
name into the constant itself.
• If we override the toString method in an enum type, we
must consider writing a fromString method to translate
the custom string representation back to the
corresponding enum.
• Enum constructors aren’t permitted to access the
enum’s static fields, except for compile-time constant
fields as the static fields have not been initialized when
the constructors run.
• A disadvantage of constant-specific method
implementations is that they make it harder to share
code among enum constants.
General
Programming
Item 45: Minimize the scope of local
variables
• It increases the readability and maintainability of
code and reduces likelihood of error.
• Always declare the variable where it is first used.
• Nearly every local variable declaration should
contain an initializer.
• Prefer for loops to while loops if the contents of the
loop variable aren’t needed after the loop
terminates.
• Keep the methods small and focused.
• Separate the methods for each activity.
Item 46: Prefer for-each loops to
traditional for loops
• It gets rid of the clutter and hides the iterator or index variable
completely.
• The colon (:) of foreach loop is read as “in.”
• There is no performance penalty but slight improvement for using the for-
each loop, even for arrays as it computes the limit of the array index only
once.
• Not only does the for-each loop let us iterate over collections and arrays,
it lets us iterate over any object that implements the Iterable interface.
• Avoid for-each for following circumstances:
• Filtering—If you need to traverse a collection and remove selected
elements, then you need to use an explicit iterator so that you can call its
remove method.
• Transforming—If you need to traverse a list or array and replace some or
all of the values of its elements, then you need the list iterator or array
index in order to set the value of an element.
• Parallel iteration—If you need to traverse multiple collections in parallel,
then you need explicit control over the iterator or index variable, so that
all iterators or index variables can be advanced in lockstep.
Common Error
• Collection<Suit> suits = Arrays.asList({ CLUB, DIAMOND, HEART,
SPADE });
• Collection<Rank> ranks = Arrays.asList({ ACE, DEUCE, THREE,
FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING });
• List<Card> deck = new ArrayList<Card>();
• for (Iterator<Suit> i = suits.iterator(); i.hasNext(); )
• for (Iterator<Rank> j = ranks.iterator(); j.hasNext(); )
• deck.add(new Card(i.next(), j.next()));
• The next method is called too many times on the iterator for
the outer collection (suits).
• It should be called from the outer loop, so that it is called once
per suit, but instead it is called from the inner loop, so it is
called once per card.
• After we run out of suits, the loop throws a
NoSuchElementException.
• Using for-each loop the above problem simply disappears.
Item 47: Know and use
the libraries
• By using a standard library, you take advantage of the
knowledge of the experts who wrote it and the experience of
those who used it before you.
• You don’t have to waste your time writing ad hoc solutions to
problems that are only marginally related to your work.
• The performance tends to improve over time by using standard
libraries.
• Standard libraries also tend to gain new functionality over time.
• Using the standard libraries places your code in the mainstream,
making it more easily readable, maintainable, and reusable by
the multitude of developers.
• Every programmer should be familiar with the contents of
java.lang, java.util, and, to a lesser extent, java.io.
• The Collections Framework was added to java.util package and
concurrency utilities added to java.util.concurrent package.
Item 48: Avoid float and double if
exact answers are required
• The float and double types are designed primarily
for scientific and engineering calculations.
• The float and double types are particularly illsuited
• for monetary calculations requiring exact answer
because it is impossible to represent 0.1 as a float or
double exactly.
• Always use BigDecimal, int, or long for monetary
calculations.
• Disadvantage of using BigDecimal is that it is less
convenient than using a primitive arithmetic type,
and is slower.
• An alternative to using BigDecimal is to use int or
long, depending on the amounts involved.
Item 49: Prefer primitive types
to boxed primitives
• Every primitive type has a corresponding reference type,
called a boxed primitive.
• The boxed primitives corresponding to int, double, and
boolean are Integer, Double, and Boolean.
• Primitives have only their values, whereas boxed
primitives have identities distinct from their values.
• Two boxed primitive instances can have the same value
and different identities.
• Primitive types have only fully functional values, whereas
each boxed primitive type has one nonfunctional value,
which is null, in addition to all of the functional values of
its corresponding primitive type.
• Primitives are generally more time and space-efficient
than boxed primitives.

Mais conteúdo relacionado

Mais procurados

Factory Design Pattern
Factory Design PatternFactory Design Pattern
Factory Design PatternJaswant Singh
 
Advanced java interview questions
Advanced java interview questionsAdvanced java interview questions
Advanced java interview questionsrithustutorials
 
Ch. 3 classes and objects
Ch. 3 classes and objectsCh. 3 classes and objects
Ch. 3 classes and objectsdkohreidze
 
Jump start to OOP, OOAD, and Design Pattern
Jump start to OOP, OOAD, and Design PatternJump start to OOP, OOAD, and Design Pattern
Jump start to OOP, OOAD, and Design PatternNishith Shukla
 
Design Patterns - Factory Method & Abstract Factory
Design Patterns - Factory Method & Abstract FactoryDesign Patterns - Factory Method & Abstract Factory
Design Patterns - Factory Method & Abstract FactoryGuillermo Daniel Salazar
 
Layers of Smalltalk Application
Layers of Smalltalk ApplicationLayers of Smalltalk Application
Layers of Smalltalk Applicationspeludner
 
Java Course 11: Design Patterns
Java Course 11: Design PatternsJava Course 11: Design Patterns
Java Course 11: Design PatternsAnton Keks
 
Common ASP.NET Design Patterns - Telerik India DevCon 2013
Common ASP.NET Design Patterns - Telerik India DevCon 2013Common ASP.NET Design Patterns - Telerik India DevCon 2013
Common ASP.NET Design Patterns - Telerik India DevCon 2013Steven Smith
 
Jump Start To Ooad And Design Patterns
Jump Start To Ooad And Design PatternsJump Start To Ooad And Design Patterns
Jump Start To Ooad And Design PatternsLalit Kale
 
Java object oriented programming - OOPS
Java object oriented programming - OOPSJava object oriented programming - OOPS
Java object oriented programming - OOPSrithustutorials
 
Introduction to Design Patterns and Singleton
Introduction to Design Patterns and SingletonIntroduction to Design Patterns and Singleton
Introduction to Design Patterns and SingletonJonathan Simon
 
Programmer testing
Programmer testingProgrammer testing
Programmer testingJoao Pereira
 
Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)Sameer Rathoud
 
P Training Presentation
P Training PresentationP Training Presentation
P Training PresentationGaurav Tyagi
 
Testdriven Development using JUnit and EasyMock
Testdriven Development using JUnit and EasyMockTestdriven Development using JUnit and EasyMock
Testdriven Development using JUnit and EasyMockschlebu
 
C# Advanced L07-Design Patterns
C# Advanced L07-Design PatternsC# Advanced L07-Design Patterns
C# Advanced L07-Design PatternsMohammad Shaker
 
Design Patterns For 70% Of Programmers In The World
Design Patterns For 70% Of Programmers In The WorldDesign Patterns For 70% Of Programmers In The World
Design Patterns For 70% Of Programmers In The WorldSaurabh Moody
 
OCA Java SE 8 Exam Chapter 6 Exceptions
OCA Java SE 8 Exam Chapter 6 ExceptionsOCA Java SE 8 Exam Chapter 6 Exceptions
OCA Java SE 8 Exam Chapter 6 Exceptionsİbrahim Kürce
 

Mais procurados (20)

Factory Design Pattern
Factory Design PatternFactory Design Pattern
Factory Design Pattern
 
Advanced java interview questions
Advanced java interview questionsAdvanced java interview questions
Advanced java interview questions
 
Ch. 3 classes and objects
Ch. 3 classes and objectsCh. 3 classes and objects
Ch. 3 classes and objects
 
Jump start to OOP, OOAD, and Design Pattern
Jump start to OOP, OOAD, and Design PatternJump start to OOP, OOAD, and Design Pattern
Jump start to OOP, OOAD, and Design Pattern
 
Design Patterns - Factory Method & Abstract Factory
Design Patterns - Factory Method & Abstract FactoryDesign Patterns - Factory Method & Abstract Factory
Design Patterns - Factory Method & Abstract Factory
 
Layers of Smalltalk Application
Layers of Smalltalk ApplicationLayers of Smalltalk Application
Layers of Smalltalk Application
 
Java Course 11: Design Patterns
Java Course 11: Design PatternsJava Course 11: Design Patterns
Java Course 11: Design Patterns
 
Common ASP.NET Design Patterns - Telerik India DevCon 2013
Common ASP.NET Design Patterns - Telerik India DevCon 2013Common ASP.NET Design Patterns - Telerik India DevCon 2013
Common ASP.NET Design Patterns - Telerik India DevCon 2013
 
Jump Start To Ooad And Design Patterns
Jump Start To Ooad And Design PatternsJump Start To Ooad And Design Patterns
Jump Start To Ooad And Design Patterns
 
Java object oriented programming - OOPS
Java object oriented programming - OOPSJava object oriented programming - OOPS
Java object oriented programming - OOPS
 
Introduction to Design Patterns and Singleton
Introduction to Design Patterns and SingletonIntroduction to Design Patterns and Singleton
Introduction to Design Patterns and Singleton
 
Go f designpatterns 130116024923-phpapp02
Go f designpatterns 130116024923-phpapp02Go f designpatterns 130116024923-phpapp02
Go f designpatterns 130116024923-phpapp02
 
Programmer testing
Programmer testingProgrammer testing
Programmer testing
 
Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)
 
P Training Presentation
P Training PresentationP Training Presentation
P Training Presentation
 
Testdriven Development using JUnit and EasyMock
Testdriven Development using JUnit and EasyMockTestdriven Development using JUnit and EasyMock
Testdriven Development using JUnit and EasyMock
 
EasyMock for Java
EasyMock for JavaEasyMock for Java
EasyMock for Java
 
C# Advanced L07-Design Patterns
C# Advanced L07-Design PatternsC# Advanced L07-Design Patterns
C# Advanced L07-Design Patterns
 
Design Patterns For 70% Of Programmers In The World
Design Patterns For 70% Of Programmers In The WorldDesign Patterns For 70% Of Programmers In The World
Design Patterns For 70% Of Programmers In The World
 
OCA Java SE 8 Exam Chapter 6 Exceptions
OCA Java SE 8 Exam Chapter 6 ExceptionsOCA Java SE 8 Exam Chapter 6 Exceptions
OCA Java SE 8 Exam Chapter 6 Exceptions
 

Destaque

Effective java
Effective javaEffective java
Effective javaHaeil Yi
 
Effective Java - Chapter 3: Methods Common to All Objects
Effective Java - Chapter 3: Methods Common to All ObjectsEffective Java - Chapter 3: Methods Common to All Objects
Effective Java - Chapter 3: Methods Common to All Objectsİbrahim Kürce
 
Effective Java - Generics
Effective Java - GenericsEffective Java - Generics
Effective Java - GenericsRoshan Deniyage
 
The Go Programing Language 1
The Go Programing Language 1The Go Programing Language 1
The Go Programing Language 1İbrahim Kürce
 
Effective Java - Enum and Annotations
Effective Java - Enum and AnnotationsEffective Java - Enum and Annotations
Effective Java - Enum and AnnotationsRoshan Deniyage
 
Effective java 1 and 2
Effective java 1 and 2Effective java 1 and 2
Effective java 1 and 2중선 곽
 
Từ Gà Đến Pro Git và GitHub trong 60 phút
Từ Gà Đến Pro Git và GitHub trong 60 phútTừ Gà Đến Pro Git và GitHub trong 60 phút
Từ Gà Đến Pro Git và GitHub trong 60 phútHuy Hoàng Phạm
 
Reactive Streams and RxJava2
Reactive Streams and RxJava2Reactive Streams and RxJava2
Reactive Streams and RxJava2Yakov Fain
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Fabio Collini
 
Sinh viên IT học và làm gì để không thất nghiệp
Sinh viên IT học và làm gì để không thất nghiệpSinh viên IT học và làm gì để không thất nghiệp
Sinh viên IT học và làm gì để không thất nghiệpHuy Hoàng Phạm
 
Lap trinh java hieu qua
Lap trinh java hieu quaLap trinh java hieu qua
Lap trinh java hieu quaLê Anh
 
Spring mvc
Spring mvcSpring mvc
Spring mvcBa Big
 
Luận văn tìm hiểu Spring
Luận văn tìm hiểu SpringLuận văn tìm hiểu Spring
Luận văn tìm hiểu SpringAn Nguyen
 
Live chym kysubrse vs toidicodedao
Live chym kysubrse vs toidicodedaoLive chym kysubrse vs toidicodedao
Live chym kysubrse vs toidicodedaoHuy Hoàng Phạm
 
Từ Sinh Viên IT tới Lập Trình Viên
Từ Sinh Viên IT tới Lập Trình ViênTừ Sinh Viên IT tới Lập Trình Viên
Từ Sinh Viên IT tới Lập Trình ViênHuy Hoàng Phạm
 
Hành trình trở thành web đì ve lốp pơ
Hành trình trở thành web đì ve lốp pơHành trình trở thành web đì ve lốp pơ
Hành trình trở thành web đì ve lốp pơHuy Hoàng Phạm
 

Destaque (17)

Effective java
Effective javaEffective java
Effective java
 
Effective Java - Chapter 3: Methods Common to All Objects
Effective Java - Chapter 3: Methods Common to All ObjectsEffective Java - Chapter 3: Methods Common to All Objects
Effective Java - Chapter 3: Methods Common to All Objects
 
Effective Java - Generics
Effective Java - GenericsEffective Java - Generics
Effective Java - Generics
 
The Go Programing Language 1
The Go Programing Language 1The Go Programing Language 1
The Go Programing Language 1
 
Effective Java - Enum and Annotations
Effective Java - Enum and AnnotationsEffective Java - Enum and Annotations
Effective Java - Enum and Annotations
 
Effective java 1 and 2
Effective java 1 and 2Effective java 1 and 2
Effective java 1 and 2
 
Từ Gà Đến Pro Git và GitHub trong 60 phút
Từ Gà Đến Pro Git và GitHub trong 60 phútTừ Gà Đến Pro Git và GitHub trong 60 phút
Từ Gà Đến Pro Git và GitHub trong 60 phút
 
Reactive Streams and RxJava2
Reactive Streams and RxJava2Reactive Streams and RxJava2
Reactive Streams and RxJava2
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
 
Spring mvc
Spring mvcSpring mvc
Spring mvc
 
Sinh viên IT học và làm gì để không thất nghiệp
Sinh viên IT học và làm gì để không thất nghiệpSinh viên IT học và làm gì để không thất nghiệp
Sinh viên IT học và làm gì để không thất nghiệp
 
Lap trinh java hieu qua
Lap trinh java hieu quaLap trinh java hieu qua
Lap trinh java hieu qua
 
Spring mvc
Spring mvcSpring mvc
Spring mvc
 
Luận văn tìm hiểu Spring
Luận văn tìm hiểu SpringLuận văn tìm hiểu Spring
Luận văn tìm hiểu Spring
 
Live chym kysubrse vs toidicodedao
Live chym kysubrse vs toidicodedaoLive chym kysubrse vs toidicodedao
Live chym kysubrse vs toidicodedao
 
Từ Sinh Viên IT tới Lập Trình Viên
Từ Sinh Viên IT tới Lập Trình ViênTừ Sinh Viên IT tới Lập Trình Viên
Từ Sinh Viên IT tới Lập Trình Viên
 
Hành trình trở thành web đì ve lốp pơ
Hành trình trở thành web đì ve lốp pơHành trình trở thành web đì ve lốp pơ
Hành trình trở thành web đì ve lốp pơ
 

Semelhante a Effective Java Static Factory Methods

Prototype design patterns
Prototype design patternsPrototype design patterns
Prototype design patternsThaichor Seng
 
Creational Patterns
Creational PatternsCreational Patterns
Creational PatternsAsma CHERIF
 
Creational Design Patterns.pptx
Creational Design Patterns.pptxCreational Design Patterns.pptx
Creational Design Patterns.pptxSachin Patidar
 
Design patterns
Design patternsDesign patterns
Design patternsAlok Guha
 
Unit testing and mocking in Python - PyCon 2018 - Kenya
Unit testing and mocking in Python - PyCon 2018 - KenyaUnit testing and mocking in Python - PyCon 2018 - Kenya
Unit testing and mocking in Python - PyCon 2018 - KenyaErick M'bwana
 
Effective java - Creating and Destroying Objects
Effective java  - Creating and Destroying ObjectsEffective java  - Creating and Destroying Objects
Effective java - Creating and Destroying ObjectsRohit Vaidya
 
Lec08 constructors
Lec08   constructorsLec08   constructors
Lec08 constructorsAsif Shahzad
 
Weekly Meeting: Basic Design Pattern
Weekly Meeting: Basic Design PatternWeekly Meeting: Basic Design Pattern
Weekly Meeting: Basic Design PatternNguyen Trung Kien
 
Javascript Common Design Patterns
Javascript Common Design PatternsJavascript Common Design Patterns
Javascript Common Design PatternsPham Huy Tung
 
Prototype presentation
Prototype presentationPrototype presentation
Prototype presentationISsoft
 

Semelhante a Effective Java Static Factory Methods (20)

Prototype design patterns
Prototype design patternsPrototype design patterns
Prototype design patterns
 
Virtual Function
Virtual FunctionVirtual Function
Virtual Function
 
Creational Patterns
Creational PatternsCreational Patterns
Creational Patterns
 
Creational Design Patterns.pptx
Creational Design Patterns.pptxCreational Design Patterns.pptx
Creational Design Patterns.pptx
 
Design patterns
Design patternsDesign patterns
Design patterns
 
Unit testing and mocking in Python - PyCon 2018 - Kenya
Unit testing and mocking in Python - PyCon 2018 - KenyaUnit testing and mocking in Python - PyCon 2018 - Kenya
Unit testing and mocking in Python - PyCon 2018 - Kenya
 
Effective java - Creating and Destroying Objects
Effective java  - Creating and Destroying ObjectsEffective java  - Creating and Destroying Objects
Effective java - Creating and Destroying Objects
 
Factory Design Pattern
Factory Design PatternFactory Design Pattern
Factory Design Pattern
 
Factory Pattern
Factory PatternFactory Pattern
Factory Pattern
 
Factory method pattern
Factory method patternFactory method pattern
Factory method pattern
 
Lec08 constructors
Lec08   constructorsLec08   constructors
Lec08 constructors
 
Prototype pattern
Prototype patternPrototype pattern
Prototype pattern
 
CONSTRUCTORS.pptx
CONSTRUCTORS.pptxCONSTRUCTORS.pptx
CONSTRUCTORS.pptx
 
Weekly Meeting: Basic Design Pattern
Weekly Meeting: Basic Design PatternWeekly Meeting: Basic Design Pattern
Weekly Meeting: Basic Design Pattern
 
Javascript Common Design Patterns
Javascript Common Design PatternsJavascript Common Design Patterns
Javascript Common Design Patterns
 
Testing Angular
Testing AngularTesting Angular
Testing Angular
 
Prototype presentation
Prototype presentationPrototype presentation
Prototype presentation
 
Prototype_pattern
Prototype_patternPrototype_pattern
Prototype_pattern
 
Design p atterns
Design p atternsDesign p atterns
Design p atterns
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 

Mais de Emprovise

Highlights of AWS ReInvent 2023 (Announcements and Best Practices)
Highlights of AWS ReInvent 2023 (Announcements and Best Practices)Highlights of AWS ReInvent 2023 (Announcements and Best Practices)
Highlights of AWS ReInvent 2023 (Announcements and Best Practices)Emprovise
 
Leadership and Success Lessons for Life/Business
Leadership and Success Lessons for Life/BusinessLeadership and Success Lessons for Life/Business
Leadership and Success Lessons for Life/BusinessEmprovise
 
Secure socket layer
Secure socket layerSecure socket layer
Secure socket layerEmprovise
 
EJB3 Advance Features
EJB3 Advance FeaturesEJB3 Advance Features
EJB3 Advance FeaturesEmprovise
 
Enterprise Java Beans 3 - Business Logic
Enterprise Java Beans 3 - Business LogicEnterprise Java Beans 3 - Business Logic
Enterprise Java Beans 3 - Business LogicEmprovise
 
RESTful WebServices
RESTful WebServicesRESTful WebServices
RESTful WebServicesEmprovise
 
J2EE Patterns
J2EE PatternsJ2EE Patterns
J2EE PatternsEmprovise
 
Spring Web Services
Spring Web ServicesSpring Web Services
Spring Web ServicesEmprovise
 
Spring Web Webflow
Spring Web WebflowSpring Web Webflow
Spring Web WebflowEmprovise
 
Spring Web Views
Spring Web ViewsSpring Web Views
Spring Web ViewsEmprovise
 
Enterprise Spring
Enterprise SpringEnterprise Spring
Enterprise SpringEmprovise
 
Spring Basics
Spring BasicsSpring Basics
Spring BasicsEmprovise
 
Apache Struts 2 Advance
Apache Struts 2 AdvanceApache Struts 2 Advance
Apache Struts 2 AdvanceEmprovise
 
Apache Struts 2 Framework
Apache Struts 2 FrameworkApache Struts 2 Framework
Apache Struts 2 FrameworkEmprovise
 
Java Servlets
Java ServletsJava Servlets
Java ServletsEmprovise
 
Java Advance Concepts
Java Advance ConceptsJava Advance Concepts
Java Advance ConceptsEmprovise
 

Mais de Emprovise (20)

Highlights of AWS ReInvent 2023 (Announcements and Best Practices)
Highlights of AWS ReInvent 2023 (Announcements and Best Practices)Highlights of AWS ReInvent 2023 (Announcements and Best Practices)
Highlights of AWS ReInvent 2023 (Announcements and Best Practices)
 
Leadership and Success Lessons for Life/Business
Leadership and Success Lessons for Life/BusinessLeadership and Success Lessons for Life/Business
Leadership and Success Lessons for Life/Business
 
Secure socket layer
Secure socket layerSecure socket layer
Secure socket layer
 
EJB3 Advance Features
EJB3 Advance FeaturesEJB3 Advance Features
EJB3 Advance Features
 
Enterprise Java Beans 3 - Business Logic
Enterprise Java Beans 3 - Business LogicEnterprise Java Beans 3 - Business Logic
Enterprise Java Beans 3 - Business Logic
 
EJB3 Basics
EJB3 BasicsEJB3 Basics
EJB3 Basics
 
RESTful WebServices
RESTful WebServicesRESTful WebServices
RESTful WebServices
 
J2EE Patterns
J2EE PatternsJ2EE Patterns
J2EE Patterns
 
Spring JMS
Spring JMSSpring JMS
Spring JMS
 
JMS
JMSJMS
JMS
 
Spring Web Services
Spring Web ServicesSpring Web Services
Spring Web Services
 
Spring Web Webflow
Spring Web WebflowSpring Web Webflow
Spring Web Webflow
 
Spring Web Views
Spring Web ViewsSpring Web Views
Spring Web Views
 
Spring MVC
Spring MVCSpring MVC
Spring MVC
 
Enterprise Spring
Enterprise SpringEnterprise Spring
Enterprise Spring
 
Spring Basics
Spring BasicsSpring Basics
Spring Basics
 
Apache Struts 2 Advance
Apache Struts 2 AdvanceApache Struts 2 Advance
Apache Struts 2 Advance
 
Apache Struts 2 Framework
Apache Struts 2 FrameworkApache Struts 2 Framework
Apache Struts 2 Framework
 
Java Servlets
Java ServletsJava Servlets
Java Servlets
 
Java Advance Concepts
Java Advance ConceptsJava Advance Concepts
Java Advance Concepts
 

Último

08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 

Último (20)

08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 

Effective Java Static Factory Methods

  • 1. Effective Java Joshua Bloch Using the Java language at its best..,
  • 3. Item 1: Consider static factory methods instead of constructors • A class can provide a public static factory method, which is simply a static method that returns an instance of the class. • A static factory method is not the same as the Factory Method pattern. • One advantage of static factory methods is that, unlike constructors, they have names, which enables describe the object being returned. • In a case where a class seems to require multiple constructors with the same signature, replace the constructors with static factory methods and carefully chosen names to highlight their differences.
  • 4. Static Factory Methods • 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. • Enables immutable classes to use preconstructed instances, or to cache instances as they’re constructed, and dispense them repeatedly to avoid creating unnecessary duplicate objects. • The ability of static factory methods to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time (instance controlled). • Instance control allows a class to guarantee that it is a singleton or noninstantiable, ensuring immutable class that no two equal instances exist.
  • 5. Interface Based Frameworks • A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type. • An API can return objects without making their classes public is called interface-based frameworks. • Nearly all Java Collections Framework implementations are exported via static factory methods in one noninstantiable class (java.util.Collections). • The class of the object returned by the static factory method can vary from invocation to invocation depending on the values of the parameters to the static factory. • The class of the object returned by a static factory method need not even exist at the time the class containing the method is written, such flexible static factory methods form the basis of service provider frameworks. E.g. JDBC. • 3 Components of service provider framework: a service interface, which providers implement; a provider registration API, which the system uses to register implementations, giving clients access to them; and a service access API, which clients use to obtain an instance of the service. • A service provider interface, which providers implement to create instances of their service implementation is the optional 4th component.
  • 6. Advantage and Disadvantages • A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized type instances. • When we invoke the constructor of a parameterized class, we must specify the type parameters. • Map<String, List<String>> m = new HashMap<String, List<String>>(); • With static factories, the compiler can figure out the type parameters, known as type inference. • 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.
  • 7. Item 2: Consider a builder when faced with many constructor parameters • In case of large numbers of optional parameters, the constructors or static factories do not scale well. • Traditionally the telescoping constructor pattern I used in such cases were only a required number of parameters is provided to the constructor, with each optional parameter added with a overloaded constructor. • If the client accidentally reverses two such parameters, the compiler won’t complain, but the program will misbehave at runtime. • Second alternative, the JavaBeans pattern which calls a parameterless constructor to create the object and then call setter methods to set each required parameter and each optional parameter of interest. • JavaBean may be in an inconsistent state partway through its construction and also precludes the possibility of making a class immutable.
  • 8. Builder Pattern • The client calls a constructor (or static factory) with all of the required parameters (instead of creating the object directly) and gets a builder object. • Then the client calls setter-like methods on the builder object to set each optional parameter of interest. • Finally, the client calls a parameterless build method to generate the object, which is immutable. • The builder’s setter methods return the builder itself so that invocations can be chained. • A builder can impose invariants on its parameters, and is critical that they be checked after copying the parameters from the builder to the object, and that they be checked on the object fields rather than the builder fields. • A minor advantage of builders over constructors is that builders can have multiple varargs parameters, as they use separate methods to set each parameter. • A single builder can be used to build multiple objects. • Disadvantage is that in order to create an object, we must first create its builder.
  • 9. • public class NutritionFacts { • private final int servingSize; • private final int servings; • private final int calories; • private final int fat; • public static class Builder { • // Required parameters • private final int servingSize; • private final int servings; • // Optional parameters - initialized to default values • private int calories = 0; • private int fat = 0; • public Builder(int servingSize, int servings) { • this.servingSize = servingSize; • this.servings = servings; • } • public Builder calories(int val) • { calories = val; return this; } • public Builder fat(int val) • { fat = val; return this; } • public NutritionFacts build() { • return new NutritionFacts(this); • } • } • private NutritionFacts(Builder builder) { • servingSize = builder.servingSize; • servings = builder.servings; • calories = builder.calories; • fat = builder.fat; • } • }
  • 10. Item 3: Enforce the singleton property with a private constructor or an enum type • A singleton is simply a class that is instantiated exactly once. • Making a class a singleton can make it difficult to test its clients. • There are two ways to implement singletons. • Both are based on keeping the constructor private and exporting a public static member to provide access to the sole instance. • One approach is a final field which is initialized by the private constructor called only once (unless using reflection to invoke private constructor). • Another approach is to have a public static factory method which return the same object reference which is initialized when class is loaded. • It makes the singleton declarations clear and provide flexibility to change the singleton class without API change. • A single-element enum type is the best way to implement a singleton
  • 11. Item 4: Enforce noninstantiability with a private constructor • Attempting to enforce noninstantiability by making a class abstract does not work. • The class can be subclassed and the subclass instantiated. • Also it misleads the user into thinking the class was designed for inheritance. • A class can be made noninstantiable by including a private constructor. • The AssertionError isn’t strictly required in the constructor, but it provides insurance in case the constructor is accidentally invoked from within the class
  • 12. Item 5: Avoid creating unnecessary objects • An object can always be reused if it is immutable. • A string object will be reused by any other code running in the same virtual machine that happens to contain the same string literal. • Static factory methods can often be used to avoid creating unnecessary objects in preference to constructors on immutable classes that provide both. • With lazy initialization, it complicates the implementation and is unlikely to result in a noticeable performance improvement beyond what is already achieved. • An adapter is an object that delegates to a backing object, providing an alternative interface to the backing object. • 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.
  • 13. Autoboxing and Reusing Objects • Autoboxing creates unnecessary objects, hence prefer primitives to boxed primitives, and watch out for unintentional autoboxing. • Creation and reclamation of small objects whose constructors do little explicit work is cheap, especially on modern JVMs. • Creating additional objects to enhance the clarity, simplicity, or power of a program is generally a good thing. • Avoiding object creation by maintaining your own object pool is a bad idea unless the objects in the pool are extremely heavyweight. • The penalty for reusing an object when defensive copying is called for is far greater than the penalty for needlessly creating a duplicate object. • Failing to make defensive copies where required can lead to insidious bugs and security holes.
  • 14. Item 6: Eliminate obsolete object references • An obsolete reference is simply a reference that will never be dereferenced again. • If an object reference is unintentionally retained, not only is that object excluded from garbage collection. • Such objects leads to memory leaks which cause disk paging and even program failure with an OutOfMemoryError • Nulling out object references before they become obsolete, should be the exception rather than the norm. • The best way to eliminate an obsolete reference is to let the variable that contained the reference fall out of scope. • Common sources of memory leaks are classes managing its own memory, caches, listeners and other callbacks.
  • 15. Item 7: Avoid finalizers • Finalizers are unpredictable, often dangerous, and generally unnecessary. • There is no guarantee that finalizer will be executed promptly after an object becomes unreachable. • Never do anything time-critical in a finalizer. • It is possible that a program terminates without executing finalizers on some objects that are no longer reachable. • Hence we should never depend on a finalizer to update critical persistent state. • Uncaught exceptions thrown during finalization are ignored, which can leave objects in a corrupt state. • There is a severe performance penalty for using finalizers, as its about 430 times slower to create and destroy objects with finalizers. • Explicit termination methods (close methods) are typically used in combination with the try-finally construct to ensure termination.
  • 17. Item 8: • Obey the general contract when overriding equals. • Do not override equals method in case of following: • Each instance of the class is inherently unique: True for classes such as Thread. • You don’t care whether the class provides a “logical equality” test: java.util.Random could have overridden equals method to check equality of two random numbers. • A superclass has already overridden equals, and the superclass behavior is appropriate for this class: Set inherits equals implementation from AbstractSet. • The class is private or package-private, and you are certain that its equals method will never be invoked.
  • 18. Equals overriding • When a class has a notion of logical equality that differs from mere object identity, and a superclass has not already overridden equals to implement the desired behavior. • Generally true for Value classes such as Integer or Date. • Overriding equals method enables instances to serve as map keys or set elements with predictable, desirable behavior. • Classes using instance control does not require equals override. Example Enums types.
  • 19. General Equals Contract • Reflexive: x.equals(x) • Symmetric: If x.equals(y) then y.equals(x) • Transitive: If x.equals(y) & y.equals(z) then x.equals(z) • Consistent: Multiple invocations of x.equals(y) • Non-Null Reference: x.equals(null) is false. • Never try to handle equality of super class objects with the subclass objects in the subclass equals method. Eg: String and CaseInsensitiveString • There is no way to extend an instantiable class and add a value component while preserving the equals contract, unless you are willing to forgo the benefits of object-oriented abstraction.
  • 20. Equating Same Implementation • Equating objects only with same implementation class • @Override public boolean equals(Object o) { • if (o == null || o.getClass() != getClass()) • return false; • Point p = (Point) o; • return p.x == x && p.y == y; • } • Violates Liskov’s subsitution principle which says that any important property of a type should also hold for its subtypes, so that any method written for the type should work equally well on its subtypes.
  • 21. Equals method: Inheritence • There is no satisfactory way to extend an instantiable class and add a value component. • Workaround is to Favor composition over inheritance. • Java.sql.Timestamp extends java.util.Date and adds nanoseconds violating symmetry. • One can add a value component to a subclass of an abstract class without violating the equals contract, as superclass instances cannot be created directly.
  • 22. • Mutable objects can be equal to different objects at different times while immutable objects can’t. • When you write a class, think hard about whether it should be immutable. • If you write immutable class, make sure that your equals method enforces the restriction that equal objects remain equal and unequal objects remain unequal for all time. • Do not write an equals method that depends on unreliable resources: java.net.URL relies on IP address. • Non-Nullity: All objects must be unequal to null, and must return false instead of NullPointerException. • The equals method must first cast its argument to an appropriate type so its accessors may be invoked or its fields accessed. • Before the cast, use the instanceof operator to check for type, which also returns false if its first operand is null, regardless of what type appears in the second operand. • Don’t substitute another type of Object in equals declaration, as it will not override Object.equals method but overloads it. Guidelines for equals method
  • 23. Recipe for Equals method • Use the == operator to check if the argument is a reference to this object. • Use the instanceof operator to check if the argument has the correct type. (Use of interface refines the equals contract to permit comparisons across classes that implement the interface.) • Cast the argument to the correct type. • For each “significant” field in the class, check if that field of the argument matches the corresponding field of this object.
  • 24. Equals: Field comparsion • If an interface access the argument fields via interface methods, else if class access fields directly. • For primitive types use the == operator for comparsions. • For object reference fields invoke the equals method recursively; • For float and double fields use Float.compare and Double.compare respectively due to NaN and -0.0f. • For array fields apply above guidelines for each element. If every element is significant use Arrays.equals methods. • Use following idiom to compare to avoid NullPointerException: • (field == null ? o.field == null : field.equals(o.field)). • Use the canonical forms for comparison for complex fields. • Compare the fields first which are more likely to differ and less expensive to compare. • Do not compare redundant fields (unless for performance) or fields which are not part of an object’s logical state.
  • 25. Item9 • Always override hashCode when you override equals. • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. • It is not required that if two objects are unequal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. • The hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified, unless it is another execution of the same application.
  • 26. HashCode Implementation • The worst implementation of hash function is to return the same hash code for every object, so that every object hashes to the same bucket degenerating hash tables to linked lists. • A good hash function tends to produce unequal hash codes for unequal objects.
  • 27. Hash Function Recipe • Store some constant nonzero value, in a variable. • For each significant field: • If the field is a boolean, compute (f ? 1 : 0). • If the field is a byte, char, short, or int, compute (int) f. • If the field is a long, compute (int) (f ^ (f >>> 32)). • If the field is a float, compute Float.floatToIntBits(f). • If the field is a double, compute Double.doubleToLongBits(f), and then hash the resulting long. • If field is an object reference and the class’s equals method compares the field by recursively invoking equals, recursively invoke hashCode on the field. Use canonical form if required. • If value of field is null, return 0. • If the field is an array, treat it as if each element were a separate field. • Compute the hash code: result = contant * result + hash_code
  • 28. Hash code guidelines • Exclude any fields that are not used in equals comparisons, or you risk violating the second provision of the hashCode contract, for computing hash code. • A nonzero initial value is used in step 1 so the hash value will be affected by initial fields whose hash value, as computed is zero, avoiding collisions. • The multiplication makes the result depend on the order of the fields, yielding a much better hash function if the class has multiple similar fields. • If the constant value chosen were even and the multiplication overflowed, information would be lost, as multiplication by 2 is equivalent to shifting. • A nice property of 31 is that the multiplication can be replaced by a shift and a subtraction for better performance. • If a class is immutable and the cost of computing the hash code is significant, the hash code could be cached rather than recalculating it each time it is requested. • Do not be tempted to exclude significant parts of an object from the hash code computation to improve performance.
  • 29. Item 10: Always override toString • The toString method should return a string which is a concise but informative representation that is easy for a person to read. • It is recommended that all subclasses override the toString method. • The toString method should return all of the interesting information contained in the object. • Specifying a format serves as a standard, unambiguous representation of the object. • Specifying a matching static factory or constructor to create an instance of the object based on string representation is always helpful. • By failing to specify a format, you preserve the flexibility to add information or improve the format in a subsequent release. • Provide programmatic access to all of the information contained in the value returned by toString. i.e. access to all fields specified in toString method.
  • 30. Item 11: Override clone judiciously • The Cloneable interface was intended as a mixin interface for objects to advertise that they permit cloning. • The primary flaw of the Cloneable interface is that it lacks a clone method, and Object’s clone method is protected. • Cloneable determines the behavior of Object’s protected clone implementation: if a class implements Cloneable, Object’s clone method returns a field-by- field copy of the object; otherwise it throws CloneNotSupportedException. • Cloneable modifies the behavior of a protected method on a superclass which is atypical for interfaces.
  • 31. Object Clone • Clone creates and returns a copy of the object. • For any Object x, the expression: • x.clone() != x is true. • x.clone().getClass() == x.getClass() is true. • x.clone().equals(x) is true. • Copying an object typically entails in creating a new instance of its class, but it may require copying of internal data structures as well. • No constructors are called for cloning. • x.clone().getClass() should be identical to x.getClass() is a weak provision in cloning. • The general assumption is that if in an subclass, super.clone is invoked then the returned object will be an instance of the subclass. • If a clone method returns an object created by a constructor, it will have a wrong class. • If you override the clone method in a nonfinal class, you should return an object obtained by invoking super.clone.
  • 32. Overriding Clone method • A class that implements Cloneable is expected to provide a properly functioning public clone method. • If every field contains a primitive value or a reference to an immutable object, the returned object may be exactly the same without any further processing. • From release 1.5, it is legal for an overriding method’s return type to be a subclass of the overridden method’s return type i.e. covariant return types. • This allows the overriding method to provide more information about the returned object and eliminates the need for casting in the client.
  • 33. Overriding Clone method • If an object contains fields that refer to mutable objects, using the simple clone implementation can be disastrous. • The reference in cloned object still points to original instance of mutable object which changes if original object changes. • If the sole constructor is called such situation could never occur. • The clone method functions as another constructor; and it must be ensured that it does no harm to the original object and that it properly establishes invariants on the clone. • The clone architecture is incompatible with normal use of final fields referring to mutable objects, except in cases where the mutable objects may be safely shared between an object and its clone. Hence final modifiers should be removed in order to make the class clonable.
  • 34. Cloning recursively insufficient • public class HashTable implements Cloneable { • private Entry[] buckets = ...; • private static class Entry { • final Object key; • Object value; • Entry next; • Entry(Object key, Object value, Entry next) { • this.key = key; • this.value = value; • this.next = next; • } • } • // Broken - results in shared internal state! • @Override public HashTable clone() { • try { • HashTable result = (HashTable) super.clone(); • result.buckets = buckets.clone(); // array references original linked list. • return result; • } catch (CloneNotSupportedException e) { • throw new AssertionError(); • } • }
  • 35. Use of Deep Copy • public class HashTable implements Cloneable { • private Entry[] buckets = ...; • private static class Entry { • ……….. • Entry(Object key, Object value, Entry next) { ………. } • // Iteratively copy the linked list headed by this Entry • Entry deepCopy() { • Entry result = new Entry(key, value, next); • for (Entry p = result; p.next != null; p = p.next) • p.next = new Entry(p.next.key, p.next.value, p.next.next); • return result; • } • } • @Override public HashTable clone() { • try { • HashTable result = (HashTable) super.clone(); • result.buckets = new Entry[buckets.length]; • for (int i = 0; i < buckets.length; i++) • if (buckets[i] != null) • result.buckets[i] = buckets[i].deepCopy(); • return result; • } catch (CloneNotSupportedException e) { • throw new AssertionError(); • } • }
  • 36. Cloning complex objects • A final approach to cloning complex objects is to call super.clone, set all of the fields in the resulting object to their virgin state, and then call higher-level methods to regenerate the state of the object. • Like a constructor, a clone method should not invoke any nonfinal methods on the clone under construction (Item 17). • If clone invokes an overridden method, this method will execute before the subclass in which it is defined has had a chance to fix its state in the clone, quite possibly leading to corruption in the clone and the original. • E.g. The put(key, value) method for cloning hash table should be final and private.
  • 37. Cloning guidelines • Object’s clone method is declared to throw CloneNotSupportedException, so public clone method should omit it as methods that don’t throw checked exceptions are easier to use. • If a class that is designed for inheritance (Item 17) overrides clone, the overriding method should mimic the behavior of Object.clone. • All classes that implement Cloneable should override clone with a public method whose return type is the class itself. • Clone method should first call super.clone and then fix any fields that need to be fixed by copying any mutable objects that comprise the internal “deep structure” of the object being cloned, and replacing the clone’s references to these objects with references to the copies. • A field representing a serial number or other unique ID or a field representing the object’s creation time will need to be fixed, even if it is primitive or immutable. (makes no sense to copy immutable classes.) • A fine approach to object copying is to provide a copy constructor or copy factory. • A copy constructor is simply a constructor that takes a single argument whose type is the class (or interface implemented by class) containing the constructor.
  • 38. Item12: Consider implementing Comparable. • The compareTo method is the sole method in the Comparable interface. • It is similar in character to Object’s equals method, except that it permits order comparisons in addition to simple equality comparisons, and it is generic. • By implementing Comparable, a class indicates that its instances have a natural ordering. • If you are writing a value class with an obvious natural ordering, such as alphabetical order, numerical order, or chronological order, you should strongly consider implementing the interface.
  • 39. General contract of compareTo • Compares this object with the specified object for order. • Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. • Throws ClassCastException if the specified object’s type prevents it from being compared to this object. • Across classes, compareTo, unlike equals, doesn’t have to work: it is permitted to throw ClassCastException if two object references being compared refer to objects of different classes.
  • 40. General contract of compareTo • If you reverse the direction of a comparison between two object references then, if the first object is less than the second, then the second must be greater than the first or vice versa. • If one object is greater than a second, and the second is greater than a third, then the first must be greater than the third. • The final provision says that all objects that compare as equal must yield the same results when compared to any other object. • Similar to equals method, there is no way to extend an instantiable class with a new value component while preserving the compareTo contract, unless you are willing to forgo the benefits of object-oriented abstraction. • To add a value component to a class that implements Comparable, don’t extend it; write an unrelated class containing an instance of the first class and provide a “view” method that returns its instance. • The equality test imposed by the compareTo method should generally return the same results as the equals method. E.g. BigDecimal compareTo method is not consistent with equals.
  • 41. Comparable implementation • As the Comparable interface is parameterized, the compareTo method is statically typed, there is no need to type check or cast its argument. • If the argument is of the wrong type, the invocation won’t even compile. • If the argument is null, the invocation should throw a NullPointerException, and it will, as soon as the method attempts to access its members. • The field comparisons in a compareTo method are order comparisons rather than equality comparisons. • If a field does not implement Comparable, or you need to use a nonstandard ordering, then explicit Comparator can be used instead.
  • 42. Guidelines for compareTo method • Compare integral primitive fields using the relational operators < and >. • For floating-point fields, use Double.compare or Float.compare in place of the relational operators, which do not obey the general contract for compareTo when applied to floating point values. • For array fields, apply these guidelines to each element. • If a class has multiple significant fields, then you must start with the most significant field and work your way down the order. • If a comparison results in anything other than zero then return the result. If all fields are equal, then return zero.
  • 44. Item13: Minimize accessiblity of classes and interfaces. • The degree to which the module hides its internal data and other implementation details from other modules distinguishes out a well-designed module. • Well designed module separates the API from its implementation. • Information hiding decouples modules, allowing isolated development/testing and increases software reuse. • Make each class or member as inaccessible as possible. • Top-level (non-nested) classes and interfaces have only two possible access levels: package-private and public. • If any class is made public, you are obligated to support it forever to maintain compatibility with consuming clients.
  • 45. Accessibility Class fields • If a package-private top-level class (or interface) is used by only one class, consider making the top-level class a private nested class of the sole class that uses it. • Make all members of class private first. • Only if another class in the same package really needs to access a member the private modifier should be removed making it package-private. • Both private and package-private members are part of a class’s implementation and do not normally impact its exported API. • If a method overrides a superclass method, it is not permitted to have a lower access level in the subclass than it does in the superclass: this restricts ability to reduce accessiblity. • It is not acceptable to make a class, interface, or member public/protected to facilitate testing. • Instance fields should never be public (Item 14), as you give up the ability to limit/enforce the values that can be stored in the field. • Even final immutable objects loose flexibility to change internal representation when made public.
  • 46. Accessibility Static fields • Restrict access to all static fields except for constants, assuming that the constants form an integral part of the abstraction provided by the class. • A nonzero-length array is always mutable, so it is wrong for a class to have a public static final array field, or an accessor that returns such a field. • public static final Thing[] VALUES = { ... };
  • 47. Item 14: In public classes, use accessor methods, not public fields • If a class is accessible outside its package, provide accessor methods, to preserve the flexibility to change the class’s internal representation. • If a class is package-private or is a private nested class, there is nothing inherently wrong with exposing its data fields. (generates less visual clutter) • Public classes should never expose mutable fields and should avoid exposing immutable fields too.
  • 48. Item 15: Minimize mutability • An immutable class is simply a class whose instances cannot be modified. • Immutable classes are easier to design and implement, less prone to errors and are more secure. • The functional approach is the one in which the methods return the result of applying the operation without modifying the state of the object. • Immutable objects are simple and are inherently thread- safe; as they do not require synchronization. • Immutable objects can be shared freely. • They can be reused by providing static factories that cache frequently requested instances to avoid creating new instances when existing ones would do.
  • 49. 5 Rule for Immutable Class • Don’t provide any methods that modify the object’s state (i.e. mutators). • Ensure that the class can’t be extended. (final class) • Make all fields final. • Make all fields private. (change internal structure) • Ensure exclusive access to any mutable components. If class has any fields that refer to mutable objects, ensure that clients of the class cannot obtain references to these objects. Never initialize such a field to a client-provided object • reference or return the object reference from an accessor.
  • 50. Immutable Objects • Not only immutable objects can be shared, but their internals can be shared too. • Immutable objects make great building blocks for other objects, whether mutable or immutable. • Immutable objects make great map keys and set elements as their values will not be changing. • The only real disadvantage of immutable classes is that they require a separate object for each distinct value. • If the immutable class implements Serializable and it contains one or more fields that refer to mutable objects, then you must provide an explicit readObject or readResolve method, or use the ObjectOutputStream.writeUnshared and ObjectInputStream.readUnshared methods, even if the default serialized form is acceptable.
  • 51. Immutable Object: Performance • The performance problem is magnified if a multistep operation is performed that generates a new object at every step, eventually discarding all objects except the final result. • In such case, first try to guess which multistep operations will be commonly required and provide them as primitives. • The package-private mutable companion class for the immutable class enables to overcome performance problems, if we can accurately predict which complex multistage operations clients will want to perform on the immutable class. • Examples: StringBuilder (String), BitSet (BigInteger).
  • 52. Design Alternatives • In order to guarantee immutability the class must be declared as final. • An alternative approach is to make all of its constructors private or package-private, and to add public static factories in place of the public constructors (Item 1). • It is a better approach as for the clients of immutable class that reside outside its package, the immutable class is effectively final because it is impossible to extend a class that comes from another package and that lacks a public or protected constructor. • Also it provides flexibility for multiple implementation classes.
  • 53. Avoid externally visible change • As stated before for Immutable classes no methods may modify the object and that all its fields must be final. • In truth, no method may produce an externally visible change in the object’s state. • Some immutable classes have one or more nonfinal fields in which they cache the results of expensive computations the first time they are needed. • If the same value is requested again, the cached value is returned, saving the cost of recalculation. • Such technique is called lazy initialization. (used in String)
  • 54. Immutable Guidelines • Classes should be immutable unless there’s a very good reason to make them mutable. • Resist the urge to write a set method for every get method. • Prefer making large value objects such as BigInteger and String as immutable. • If a class cannot be made immutable, limit its mutability as much as possible. • Try to make every field final unless there is a compelling reason to make it nonfinal. (reducing number of states). • Don’t provide a public initialization method separate from the constructor or static factory unless there is a compelling reason to do so. • Don’t provide a “reinitialize” method that enables an object to be reused as if it had been constructed with a different initial state.
  • 55. Item 16: Favor composition over inheritance • It is safe to use inheritance within a package, where the subclass and the superclass implementations are under the control of the same programmers. • It is also safe to use inheritance when extending classes specifically designed and documented for extension (Item 17). • Inheriting from ordinary concrete classes across package boundaries, however, is dangerous. • Unlike method invocation, inheritance violates encapsulation.
  • 56. Dependency in Inheritence • In inheritance, a subclass depends on the implementation details of its superclass for its proper function. • If the superclass’s implementation changes after a release, the subclass may break, even though its code is untouched. • Hence a subclass must evolve in tandem with its superclass, unless the superclass’s authors have designed and documented it specifically for the purpose of being extended. • E.g. Internally, HashSet’s addAll method is implemented on top of its add method. • Reimplementing superclass methods for self-use is difficult, time-consuming, error-prone and not always possible as some methods require access to superclass private fields which are inaccessible to the subclass
  • 57. Fragility in Subclasses • A related cause of fragility in subclasses is that their superclass can acquire new methods in subsequent releases. • Securing all the methods (by overriding) for an operation to satisfy a predicate may not work if a new method capable of doing the same operation is added in superclass. • Even if we don’t override existing methods and try to add new methods in subclass, the superclass can acquire a new method in a subsequent release which has the same signature but a different return type than the method in subclass, causing subclass method to no longer compile. • If you’ve given the subclass a method with the same signature and return type as the new superclass method, then you’re now overriding it.
  • 58. Alternative: Composition • Instead of extending an existing class, use composition to give the new class a private field that references an instance of the existing class. • In composition design the existing class becomes a component of the new one. • Each instance method in the new class invokes the corresponding method on the contained instance of the existing class and returns the results, known as forwarding, and the methods in the new class are known as forwarding methods. • The resulting class will have no dependencies on the implementation details of the existing class. • Even adding new methods to the existing class will have no impact on the new class.
  • 59. Wrapper Classes • Unlike the inheritance-based approach, which works only for a single concrete class and requires a separate constructor for each supported constructor in the superclass, the wrapper class can be used with any Superclass implementation and will work in conjunction with any preexisting constructor. • Wrapper classes fall in the Decorator pattern as they decorate the superclass by adding functionality. • When the wrapper object passes itself to the wrapped object then only it is a delegation.
  • 60. Wrapper class and Forwarding methods • Wrapper classes are not suitable for callback frameworks as a wrapped object doesn’t know about its wrapper, and it passes a reference to itself (this) which the callbacks elude as the wrapper (SELF Problem). • It is tedious to write forwarding methods, but we can write the forwarding class for each interface only once (in the package of the interface).
  • 61. When to use Inheritance • Inheritance is appropriate only in circumstances where the subclass really is a subtype of the superclass (“is-a” relationship exists between the two classes). • Before extending class A by class B, as the question: Is every Class B really an Class A ? • If A is not an essential part of B, merely a detail of its implementation then use composition. • E.g. of violations: Stack extending Vector, Properties extending HashTable. • If used inheritance where composition is appropriate, unnecessary implementation details are exposed. • The resulting API ties to the original implementation, forever limiting the performance of subclass, leads to confusing semantics and enables the client to corrupt invariants of the subclass by modifying the superclass directly. • Does the class you contemplate to extend have any flaws in its API ? • Are you comfortable propograting those flaws into your class ?
  • 62. Item 17: Design and document for inheritance or else prohibit it • The class must document precisely the effects of overriding any method (i.e. self-use of overridable methods). • For each public or protected method or constructor, the documentation must indicate which overridable methods the method or constructor invokes, in what sequence, and how the results of each invocation affect subsequent processing. • A class must document any circumstances under which it might invoke an overridable method. • By convention, a method that invokes overridable methods contains a description of these invocations at the end of its documentation comment. • This violates the rule that good API documentation should describe what a given method does and not how it does it? (as Inheritance violates Encpsulation) • To document a class so that it can be safely subclassed, you must describe implementation details that should otherwise be left unspecified. • A class may have to provide hooks into its internal workings in the form of judiciously chosen protected methods or, in rare instances, protected fields. • E.g. The removeRange method from java.util.AbstractList is provided solely to make it easy for subclasses to provide a fast clear method on sublists.
  • 63. Overriding Methods • A class should expose as few protected members as possible, because each one represents a commitment to an implementation detail. • On the other hand, should not expose too few, as a missing protected member can render a class practically unusable for inheritance. • The only way to test a class designed for inheritance is to write subclasses. • Constructors must not invoke overridable methods, directly or indirectly. • The overriding method in the subclass will get invoked before the subclass constructor has run. • Avoid a class designed for inheritance implement Clonable or Serializable. • Neither clone nor readObject may invoke an overridable method, directly or indirectly. (failure can damage original object) • A class having the readResolve or writeReplace methods should be made protected rather than private. • To avoid subclassing related bugs, prohibit subclassing in classes that are not designed and documented to be safely subclassed. (use final or make constructors private and use public static factories) • If inheritance must be allowed for the class, ensure that the class never invokes any of its overridable methods and to document this fact.
  • 64. Item 18: Prefer interfaces to abstract classes • Basic difference is that abstract classes are permitted to contain implementations for some methods while interfaces are not. • Existing classes can be easily retrofitted to implement a new interface. (just add required methods and implements clause) • On other hand, existing classes cannot, in general, be retrofitted to extend a new abstract class. • In order to have two classes extending the same abstract class, the abstract class should be placed high up in the type hierarchy where it subclasses an ancestor of both the classes. • Interfaces are ideal for defining mixins. • A mixin is a type that a class can implement in addition to its “primary type” to declare that it provides some optional behavior. E.g. Comparable interface. • Mixin interface allows the optional functionality to be “mixed in” to the type’s primary functionality.
  • 65. Pros of Interfaces • Interfaces allow the construction of nonhierarchical type frameworks. • E.g. Singer and Songwriter interface can be implemented together. • The alternative is a bloated class hierarchy containing a separate class for every supported combination of attributes. • If there are n attributes in the type system, then there are 2n possible combinations that might need to be supported (a combinatorial explosion). • Bloated class hierarchies can lead to bloated classes containing many methods that differ only in the type of their arguments, as there are no types in the class hierarchy to capture common behaviors. • Interfaces enable safe, powerful functionality enhancements via the wrapper class idiom, • If you use abstract classes to define types, no alternative for composition but to use inheritance .
  • 66. Skeletal Implementation • Using interfaces to define types does not prevent us from providing abstract implementations. • One can combine the virtues of interfaces and abstract classes by providing an abstract skeletal implementation class to go with each nontrivial interface that is exported. • The skeletal implementation does the task of implementing the interface. • Skeletal implementations are called AbstractInterface, such as AbstractCollection, AbstractSet etc. • Skeletal implementations can be easily extended with a concrete implementation and exposed as an Adapter using static factories.
  • 67. Skeletal Implementation • The skeletal implementations provide the implementation assistance of abstract classes without imposing the severe constraints which abstract classes impose when they serve as type definitions. • Extending Skeletal Implementation is a choice, but is strictly optional (as interface can be implemented directly). • The class implementing the interface can forward invocations of interface methods to a contained instance of a private inner class that extends the skeletal implementation (known as simulated multiple inheritance). • To write skeletal implementations, first study the interface deciding the primitive (abstract) methods and provide concrete implementations for all the other methods.
  • 68. Simple Implementation and Interface disadvantages • A simple implementation is similar to skeletal implementation which implements an interface and is designed for inheritance, but it differs in that it isn’t abstract: it is the simplest possible working implementation. • Using abstract classes to define types has one advantage over interface: It is far easier to evolve an abstract class than an interface. • If, in a subsequent release, we want to add a new method to an abstract class, it is always possible to add a concrete method containing a reasonable default implementation. • Once an interface is released and widely implemented, it is almost impossible to change. • When ease of evolution is deemed more important than flexibility and power then abstract classes are preferred over interfaces to define a type.
  • 69. Item 19: Use interfaces only to define types • When a class implements an interface, the interface serves as a type that can be used to refer to instances of the class. • Constant interface on other hand contains no methods but solely static final fields, each exporting a constant. • The constant interface pattern is a poor use of interfaces. • Implementing a constant interface causes the implementation detail of using constants to leak into the class’s exported API. • Constant interface creates confusion among clients, adds worse commitments (as in future the constants might not be used by the class still implementing interface to ensure binary compatibility). • If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface. E.g. java.io.ObjectStreamConstants • If the constants are strongly tied to an existing class or interface, you should add them to the class or interface. • If the constants are best viewed as members of an enumerated type, they should export them as an enum type or with a noninstantiable utility class.
  • 70. Item 20: Prefer class hierarchies to tagged classes • A class whose instances come in two or more flavors and contain a tag field indicating the flavor of the instance is called a tagged class. • These classes are cluttered with boilerplate, including enum declarations, tag fields, and switch statements. • Readability is further harmed and Memory footprint is increased (due to irrelevant fields of other flavors). • Fields can’t be made final unless constructors initialize irrelevant fields, resulting in more boilerplate. • Constructors must set the tag field and initialize the right data fields without any compiler help. • To add a new flavor to a tagged class the source file needs to be modified. • The data type of an instance gives no clue as to its flavor. • To transform tagged class to class hierarchy, define an abstract class containing abstract methods which depend on tag value and add common methods independent of the tag value. • Define a concrete subclass of the root class for each flavor of the original tagged class containing data fields for its flavor.
  • 71. Item 21: Use function objects to represent strategies • Function pointer, delegates allow programs to store and transmit the ability to invoke a particular function. • They are used to allow the caller of a function to specialize its behavior by passing in a second function. • Invoking a method on an object typically performs some operation on that object. • Function objects are the objects whose methods perform operations on other objects, passed explicitly to the methods. • The strategy interface represents the strategy to use function objects. E.g. Comparator interface (with compareTo method) • The concrete strategy classes implement strategy interface. • They are stateless (no fields), preferred to be singleton • When a concrete strategy is used only once, it is typically declared and instantiated as an anonymous class. • When a concrete strategy is designed for repeated use, it is generally implemented as a private static member class and exported in a public static final field whose type is the strategy interface.
  • 72. Item 22: Favor static member classes over nonstatic • A nested class should exist only to serve its enclosing class. • There are four kinds of nested classes: • static member classes, nonstatic member classes, anonymous classes, and local classes. • A static member class is as a public helper class, useful only in conjunction with its outer class. • An instance of a nonstatic member class is implicitly associated with an enclosing instance of its containing class. • One can invoke methods on the enclosing instance or obtain a reference to the enclosing instance using the qualified this construct. • It is impossible to create an instance of a nonstatic member class without an enclosing instance. • Association between nonstatic member class instance and its enclosing instance is established automatically when the former is created and cannot be modified.
  • 73. Non-Static Member Class • Nonstatic member class is used to define an Adapter that allows an instance of the outer class to be viewed as an instance of some unrelated class. • E.g. Map has nonstatic member implementing collection views which are returned by Map’s keySet, entrySet. • If you declare a member class that does not require access to an enclosing instance, always put the static modifier in its declaration. • Storing an extraneous reference to enclosing instance costs time and space, and avoids been garbage collected. • A common use of private static member classes is to represent components of the object represented by their enclosing class. E.g. Map and Entry
  • 74. Anonymous Class • An anonymous class is not a member of its enclosing class and cannot have any static members. • They are simultaneously declared and instantiated at the point of use. • Limitations are cannot instantiate except at the point of declaration and cannot use instanceof tests. • Common use of anonymous classes is to create function objects or process objects on the fly. • If we need to create instances from only one location and there is a preexisting type that characterizes the class, make it an anonymous class; otherwise, make it a local class.
  • 76. Item 23: Don’t use raw types in new code • A class or interface whose declaration has one or more type parameters is a generic class or interface. • List interface has a single type parameter, E, representing the element type of the list. • Generic classes and interfaces are collectively known as generic types. • List<String> is a parameterized type representing a list whose elements are of type String. (String is the actual type parameter corresponding to the formal type parameter E.) • Each generic type defines a raw type (without any accompanying actual type parameters)
  • 77. Advantages of Generics • Using generics, an erroneous insertion in collections generates a compile-time error message that tells exactly what is wrong. • Added benefit is we no longer have to cast manually when removing elements from collections as compiler inserts invisible casts for us. • It is still legal to use collection types and other generic types without supplying type parameters, but should be avoided. • If you use raw types, you lose all the safety and expressiveness benefits of generics.
  • 78. Prefer Object parameterized type over raw type • It is fine to use types that are parameterized to allow insertion of arbitrary objects, such as List<Object>. • The raw type List opts out generic type checking, while List<Object> explicitly tells the compiler that it is capable of holding objects of any type. • Set<Object> is a parameterized type representing a set that can contain objects of any type. • While we can pass a List<String> to a parameter of type List, we can’t pass it to a parameter of type List<Object>. • List<String> is a subtype of the raw type List, but not of the parameterized type List<Object>. • We lose type safety if you use a raw type like List, but not if we use a parameterized type like List<Object>.
  • 79. Unbounded Wildcard Types • In case we want to write a method that takes two sets and returns the number of elements they have in common. • Instead of using raw types use unbounded wildcard types. • If we want to use a generic type but you don’t know or care what the actual type parameter is, we can use a question mark instead. • E.g. The unbounded wildcard type for the generic type Set<E> is Set<?>. • Set<?> is a wildcard type representing a set that can contain only objects of some unknown type. • We cannot put any element (other than null) into a Collection<?> and cannot assume anything about the type of the objects that we get out.
  • 80. Exceptions for using Raw Types • Two minor exceptions for not using raw types: • Raw types must be used in class literals. • E.g. List.class, String[].class, and int.class are all legal, but List<String>.class and List<?>.class are not legal. • As generic type information is erased at runtime, it is illegal to use the instanceof operator on parameterized types other than unbounded wildcard types. • if (o instanceof Set) { // Raw type • Set<?> m = (Set<?>) o; // Wildcard type • }
  • 81. Item 24: Eliminate unchecked warnings • Eliminate every unchecked warning that you can. • If you can eliminate all warnings, you are assured that your code is typesafe. • Every unchecked warning represents the potential for a ClassCastException at runtime. • If you can’t eliminate a warning, and you can prove that the code that provoked the warning is typesafe, then (and only then) suppress the warning with an @SuppressWarnings("unchecked") annotation. • The SuppressWarnings annotation can be used at any granularity, from an individual local variable declaration to an entire class. • Always use the SuppressWarnings annotation on the smallest scope possible. • It is illegal to put a SuppressWarnings annotation on the return statement, because it isn’t a declaration. • Every time you use an @SuppressWarnings("unchecked") annotation, add a comment saying why it’s safe to do so.
  • 82. Item 25: Prefer lists to arrays • Arrays are covariant i.e. if Sub is a subtype of Super, then the array type Sub[] is a subtype of Super[]. • Generics, by contrast, are invariant, i.e. for any two distinct types Type1 and Type2, List<Type1> is neither a subtype nor a supertype of List<Type2>. • // Fails at runtime! • Object[] objectArray = new Long[1]; • objectArray[0] = "I don't fit in"; // Throws ArrayStoreException • // Won't compile! • List<Object> ol = new ArrayList<Long>(); // Incompatible types • ol.add("I don't fit in");
  • 83. Arrays and Generics • With generics we find out incompatible type errors at compile time compared to arrays. • Arrays are reified i.e. arrays know and enforce their element types at runtime. • Generics, by contrast, are implemented by erasure, i.e. they enforce their type constraints only at compile time and discard (or erase) their element type information at runtime. • Erasure is allows generic types to interoperate freely with legacy code that does not use generics. • Due to such differences, arrays and generics do not mix well. • It is illegal to create an array of a generic type, a parameterized type, or a type parameter (as it isn’t typesafe) . E.g. List<E>[], new List<String>[], new E[] gives compile time error.
  • 84. Why generic array creation is illegal • List<String>[] stringLists = new List<String>[1]; // (1) • List<Integer> intList = Arrays.asList(42); // (2) • Object[] objects = stringLists; // (3) • objects[0] = intList; // (4) • String s = stringLists[0].get(0); // (5) • Line 3 stores the List<String> array into an Object array variable, which is legal because arrays are covariant. • Line 4 stores the List<Integer> into the sole element of the Object array, which succeeds because the runtime type of a List<Integer> instance is simply List, and the runtime type of a List<String>[] instance is List[], so this assignment doesn’t generate an ArrayStoreException.
  • 85. NonReifiable Types • Types such as E, List<E>, and List<String> are technically known as nonreifiable types. • A non-reifiable type is one whose runtime representation contains less information than its compile-time representation. • Unbounded wildcard types such as List<?> and Map<?,?> are the only parameterized types that are reifiable. • It is legal, to create arrays of unbounded wildcard types. • As generic array creation is prohibited, it is not generally possible for a generic type to return an array of its element type. • Also if the element type of an varargs array is not reifiable, we get a warning. • The best solution is often to use the collection type List<E> in preference to the array type E[], sacrificing some performance or conciseness in exchange for better type safety and interoperability.
  • 86. Casting using nonreifiable types • static void someMethod(List<E> list) { • E[] snapshot = (E[]) list.toArray(); // gives warning • } • The compiler can’t check the safety of the cast at runtime because it doesn’t know what E is at runtime (as element type information is erased from generics at runtime). • The compiletime type of snapshot is E[] which could be String[], Integer[], or any other kind of array, while the runtime type is Object[]. • Casts to arrays of non-reifiable types should be used only under special circumstances (Item 26). • Summary: Arrays are covariant and reified; generics are invariant and erased. Hence arrays provide runtime type safety but not compile-time type safety and vice versa for generics.
  • 87. Item 26: Favor generic types • Prefer generification of the class. • The first step in generifying a class is to add one or more type parameters to its declaration. • The conventional name of such type parameter is E. • The next step is to replace all the uses of the type Object with the appropriate type parameter, and then try to compile the resulting program. • The common compilation error when we write a generic type that is backed by an array is that we can’t create an array of a non-reifiable type (i.e. E). • E[] elements = new E[DEFAULT_CAPACITY]; • First solution is to create an array of Object and cast it to the generic array type. • E[] elements = (E[]) new Object [DEFAULT_CAPACITY]; • Suppress the warning if the array is private and never passed outside to any other methods, and only elements stored in array are of type E.
  • 88. Can’t create an array of a non-reifiable type • Second solution is to change the type of the field elements from E[] to Object[] and cast every element retrieved from the array, from Object to E. • Object[] elements = new Object [DEFAULT_CAPACITY]; • E result = (E) elements [--size]; • It is riskier to suppress an unchecked cast to an array type than to a scalar type, suggesting the second solution as better solution. • But second solution requires casts to E for every read operation compared to single cast to E[].
  • 89. Bounded type parameter • It is not always possible or desirable to use lists inside the generic types instead of arrays. • Java doesn’t support lists natively, so some generic types, such as ArrayList, must be implemented atop arrays. • We cannot create a Class object of primitive type, i.e. Stack<int>, as it results in compile time error (instead use boxed primitive types). • class DelayQueue<E extends Delayed> implements BlockingQueue<E>; • The type parameter list (<E extends Delayed>) requires that the actual type parameter E must be a subtype of java.util.concurrent.Delayed. • It allows the DelayQueue implementation and its clients to take advantage of Delayed methods on the elements of a DelayQueue, without the need for explicit casting or the risk of a ClassCastException. • The type parameter E is known as a bounded type parameter. • Note that the subtype relation is defined so that every type is a subtype of itself, hence it is legal to create a DelayQueue<Delayed>.
  • 90. Item 27: Favor generic methods • Static utility methods are particularly good candidates for generification. • To make the method typesafe, modify the method declaration to declare a type parameter representing the element type <E> for the arguments and the return value and use the type parameter in the method. • The type parameter list <E>, which declares the type parameter, goes between the method’s modifiers and its return type (i.e. Set<E>). • One restriction is that all the method parameters and return value type has to be of the same type.
  • 91. Type Inference • We don’t need to specify the value of the type parameter explicitly for generic methods as we must when invoking generic constructors. • The compiler figures out the value of the type parameters by examining the types of the method arguments. • The compiler sees that both arguments if of type e.g. String, and hence know that type parameter E must be String. Such process is called Type Inference. • Type inference can be used to ease the process of creating parameterized type instances. • public static <K,V> HashMap<K,V> newHashMap() { • return new HashMap<K,V>(); • } • Map<String, List<String>> anagrams = newHashMap();
  • 92. Generic Singleton Pattern • We need to create an object that is immutable but applicable to many different types occasionally. • Because generics are implemented by erasure (Item 25), we can use a single object for all required type parameterizations. • Although we do need to write a static factory method to repeatedly dole out the object for each requested type parameterization. • Such pattern is used in function objects such as Collections.reverseOrder. • // Generic singleton factory pattern • private static UnaryFunction<Object> IDENTITY_FUNCTION = • new UnaryFunction<Object>() { • public Object apply(Object arg) { return arg; } • }; • // IDENTITY_FUNCTION is stateless (returns arg unmodified) and its type parameter is unbounded so it's safe to share one instance across all types. • @SuppressWarnings("unchecked") • public static <T> UnaryFunction<T> identityFunction() { • return (UnaryFunction<T>) IDENTITY_FUNCTION; • }
  • 93. Recursive Type Bound • It is permissible for a type parameter to be bounded by some expression involving that type parameter itself known as a recursive type bound. • The most common use of recursive type bounds is in connection with the Comparable interface which defines natural ordering. • The type parameter T defines the type to which elements of the type implementing Comparable<T> can be compared. • Nearly, all types can be compared only to elements of their own type. String implements Comparable<String> • // Using a recursive type bound to express mutual comparability • public static <T extends Comparable<T>> T max(List<T> list) {...}
  • 94. Item 28: Use bounded wildcards to increase API flexibility • Parameterized types are invariant i.e. for any two distinct types Type1 and Type2, List<Type1> is neither a subtype nor a supertype of List<Type2>. • More flexibility is needed than invariant typing can provide. • E.g. Suppose we have a Stack<Number> and if we invoke push(intVal), where intVal is of type Integer, even Integer is subtype of Number it gives error message. • public void pushAll(Iterable<E> src) { • for (E e : src) { push(e); } • }
  • 95. Bounded Wildcard Type • The type of the input parameter to pushAll can be changed from “Iterable of E” to “Iterable of some subtype of E” using the wildcard type : Iterable<? extends E>. • Similarly, if we have a Stack<Number> and a variable of type Object, and if we try to pop an element from the stack and store in the variable, it fails (even though Object is subtype of Number). • public void popAll(Collection<E> dst) { • while (!isEmpty()) { dst.add(pop()); } • } • The type of input parameter to popAll can be changed from “collection of E” to “collection of some supertype of E” using rhe wildcard type: Collection<? super E>.
  • 96. producer-extends : consumer-super • For maximum flexibility, use wildcard types on input parameters that represent producers or consumers. • If an input parameter is both a producer and a consumer, then wildcard types will do no good: you need an exact type match i.e. without any wildcards. • PECS stands for producer-extends, consumer-super. • If a parameterized type represents a T producer, use <? extends T>; if it represents a T consumer, use <? super T>. • Do not use wildcard types as return types. • Rather than providing additional flexibility for your users, wildcard on return types forces them to use wildcard types in client code. • If the user of a class has to think about wildcard types, there is probably something wrong with the class’s API.
  • 97. Explicit Type Parameter • If the compiler doesn’t infer the type that you wish it had, you can tell it what type to use with an explicit type parameter. • Set<Number> numbers = Union.<Number>union(integers, doubles); • Comparables are always consumers, so we should always use Comparable<? super T> in preference to Comparable<T>. • Similarly we should always use Comparator<? super T> in preference to Comparator<T>. • This allows us to apply the methods declared to Collections<E> even though its element type E does not implement Comparable<E>, but is a subinterface S which extends Comparable<S>.
  • 98. Common Errors • In case of below incompatible type: • public static <T extends Comparable<? super T>> T max(List<? extends T> list) { • Iterator<T> i = list.iterator(); • } • Means that list is not a List<T>, so its iterator method doesn’t return Iterator<T>. • It returns an iterator of some subtype of T, so we replace the iterator declaration which uses a bounded wildcard type: • Iterator<? extends T> i = list.iterator();
  • 99. Dual Declarations • Dual declarations are possible with one using unbounded type parameter while the other using an unbounded wildcard. • public static <E> void swap(List<E> list, int i, int j); • public static void swap(List<?> list, int i, int j); • If a type parameter appears only once in a method declaration, replace it with a wildcard. • If unbounded replace by unbounded wildcard; if bounded replace by bounded wildcard type parameter. • Private generic helper methods to capture wildcard type need to be added to avoid issues (e.g. we cannot put any value except null into a List<?> as we can get any value out).
  • 100. Item 29: Consider typesafe heterogeneous containers • In all use of generics the container is parameterized, and limits to a fixed number of type parameters per container. • In a case were database row with many columns should all be accessible in a typesafe manner, parameterizing the key instead of the container is helpful. • In such approach, we present the parameterized key to the container to insert or retrieve a value. • The generic type system is used to guarantee that the type of the value agrees with its key.
  • 101. Typesafe heterogeneous Container • The Class object plays the part of the parameterized key as the class Class was generified in release 1.5. • The type of a class literal is no longer simply Class, but Class<T>. E.g. String.class is of type Class<String>. • When a class literal is passed among methods to communicate both compile-time and runtime type information, it is called a type token. • E.g. Below is the Favorite class API: • public class Favorites { • public <T> void putFavorite(Class<T> type, T instance); • public <T> T getFavorite(Class<T> type); • } • A Favorites instance is typesafe: it will never return an Integer when you ask it for a String; and heterogeneous: unlike an ordinary map, all the keys are of different types.
  • 102. Favorite Class Example • Each Favorites instance is backed by a private Map<Class<?>, Object>. • The wildcard type is nested i.e. it’s not the type of the Map that’s a wildcard type but the type of its key. Hence every key can have a different parameterized type. • The Map does not guarantee the type relationship between keys and values, which is that every value is of the type represented by its key. • A dynamic cast is used to cast the object reference to the type represented by the Class object, using Class’s cast method in the get implementation. • The cast method simply checks that its argument is an instance of the type represented by the Class object. If so, then returns the argument, else throws a ClassCastException.
  • 103. Casting and Bounded Type • The signature of the cast method takes full advantage of the fact that class Class has been generified, with its return type being the type parameter if the Class object. • public class Class<T> { T cast(Object obj); } • An instanceof check can be used to ensure that the put impementation never violates its type invariant. Also used by checkedlist, checkedset etc. • Favorite Class cannot be used on a non-reifiable type. i.e. String or String[] can be stored but not List<String>. • The type tokens used by Favorites can be bounded simply by a type token that places a bound on what type can be represented, using a bounded type parameter or a bounded wildcard.
  • 104. The asSubclass Method • Suppose we have an object of type Class<?> and we want to pass it to a method that requires a bounded type token such as Class<T> annotationType. • We could cast the object to Class<? extends Annotation>, but this cast is unchecked, so it would generate a compile-time warning. • class Class provides an instance method called asSubclass that performs such cast safely. • The asSubclass method casts the Class object on which it’s called to represent a subclass of the class represented by its argument. • If the cast succeeds, the method returns its argument; if it fails, it throws a ClassCastException.
  • 106. Item 30: Use enums instead of int constants • An enumerated type is a type whose legal values consist of a fixed set of constants, such as the seasons of the year. • Int enum pattern is a common pattern to declare a group of named int constants, one for each member of the type. • Int enum pattern are compile-time-constants and required to be recompiled when changed. • There is no easy way to translate int enum constants into printable strings. • There is no reliable way to iterate over all the int enum constants in a group, or even to obtain the size of an int enum group. • The variant of int enum pattern were String constants are used in place of int constants is known as the String enum pattern. • As it relies on string comparisons it faces performance problems. • Java’s enum types are classes that export one instance for each enumeration constant via a public static final field. • Enum types are effectively final, by virtue of having no accessible constructors, hence having no instances but only enum constants.
  • 107. Benefits of Enum Types • Enums provide compile-time type safety, as attempts to pass values of the wrong type will result in compile-time errors, as will attempts to assign an expression of one enum type to a variable of another, or to use the == operator to compare values of different enum types. • Enum types with identically named constants coexist peacefully as each type has its own namespace. • We can add or reorder constants in an enum type without recompiling its clients because the fields that export the constants provide a layer of insulation between an enum type and its clients. • Also enum types let us add arbitrary methods and fields and implement arbitrary interfaces.
  • 108. Methods in Enum Types • Methods in enum types enable to associate data with its constants. • E.g. Planet types has a mass and a radius from which surface gravity can be computed which in turns enables to calculate mass of object on the planet. • public enum Planet { • MERCURY(3.302e+23, 2.439e6), • VENUS (4.869e+24, 6.052e6), ……………. • } • The numbers in parentheses after each enum constant are parameters that are passed to its constructor.
  • 109. More on enum methods • To associate data with enum constants, declare instance fields and write a constructor that takes the data and stores it in the fields. • Enums are by their nature immutable, so all fields should be final and preferably private. • Enums can have static methods such as values method that returns an array of its values in the order they were declared, or toString method that returns the declared name of each enum value. • Java’s printf method uses %n where you’d use n. • If an enum is generally useful, it should be a top- level class; if its use is tied to a specific top-level class, it should be a member class of that top-level class.
  • 110. Constant-specific method implementations • Sometimes we need to associate fundamentally different behavior with each constant, e.g. an enum type representing operations on a basic four-function calculator, with a method to perform the arithmetic operation represented by each constant (usually handled by switch statement). • The code is fragile as we add a new enum constant but may forget to add a corresponding case to the switch, compiling but failing at runtime. • Declare an abstract (e.g. apply) method in the enum type, and override it with a concrete method for each constant in a constant-specific class body. • Such methods are knows as constant-specific method implementations. • As abstract methods in an enum type must be overridden with concrete methods in all of its constants, compiler gives error if method is not implemented. • Constant-specific method implementations can be combined with constant specific data.
  • 111. Constant specific class • public enum Operation { • PLUS("+") { • double apply(double x, double y) { return x + y; } • }, • MINUS("-") { • double apply(double x, double y) { return x - y; } • }, • TIMES("*") { • double apply(double x, double y) { return x * y; } • }, • DIVIDE("/") { • double apply(double x, double y) { return x / y; } • }; • • private final String symbol; • Operation(String symbol) { this.symbol = symbol; } • @Override public String toString() { return symbol; } • • abstract double apply(double x, double y); • }
  • 112. Enum constant methods • Enum types have an automatically generated valueOf(String) method that translates a constant’s name into the constant itself. • If we override the toString method in an enum type, we must consider writing a fromString method to translate the custom string representation back to the corresponding enum. • Enum constructors aren’t permitted to access the enum’s static fields, except for compile-time constant fields as the static fields have not been initialized when the constructors run. • A disadvantage of constant-specific method implementations is that they make it harder to share code among enum constants.
  • 114. Item 45: Minimize the scope of local variables • It increases the readability and maintainability of code and reduces likelihood of error. • Always declare the variable where it is first used. • Nearly every local variable declaration should contain an initializer. • Prefer for loops to while loops if the contents of the loop variable aren’t needed after the loop terminates. • Keep the methods small and focused. • Separate the methods for each activity.
  • 115. Item 46: Prefer for-each loops to traditional for loops • It gets rid of the clutter and hides the iterator or index variable completely. • The colon (:) of foreach loop is read as “in.” • There is no performance penalty but slight improvement for using the for- each loop, even for arrays as it computes the limit of the array index only once. • Not only does the for-each loop let us iterate over collections and arrays, it lets us iterate over any object that implements the Iterable interface. • Avoid for-each for following circumstances: • Filtering—If you need to traverse a collection and remove selected elements, then you need to use an explicit iterator so that you can call its remove method. • Transforming—If you need to traverse a list or array and replace some or all of the values of its elements, then you need the list iterator or array index in order to set the value of an element. • Parallel iteration—If you need to traverse multiple collections in parallel, then you need explicit control over the iterator or index variable, so that all iterators or index variables can be advanced in lockstep.
  • 116. Common Error • Collection<Suit> suits = Arrays.asList({ CLUB, DIAMOND, HEART, SPADE }); • Collection<Rank> ranks = Arrays.asList({ ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING }); • List<Card> deck = new ArrayList<Card>(); • for (Iterator<Suit> i = suits.iterator(); i.hasNext(); ) • for (Iterator<Rank> j = ranks.iterator(); j.hasNext(); ) • deck.add(new Card(i.next(), j.next())); • The next method is called too many times on the iterator for the outer collection (suits). • It should be called from the outer loop, so that it is called once per suit, but instead it is called from the inner loop, so it is called once per card. • After we run out of suits, the loop throws a NoSuchElementException. • Using for-each loop the above problem simply disappears.
  • 117. Item 47: Know and use the libraries • By using a standard library, you take advantage of the knowledge of the experts who wrote it and the experience of those who used it before you. • You don’t have to waste your time writing ad hoc solutions to problems that are only marginally related to your work. • The performance tends to improve over time by using standard libraries. • Standard libraries also tend to gain new functionality over time. • Using the standard libraries places your code in the mainstream, making it more easily readable, maintainable, and reusable by the multitude of developers. • Every programmer should be familiar with the contents of java.lang, java.util, and, to a lesser extent, java.io. • The Collections Framework was added to java.util package and concurrency utilities added to java.util.concurrent package.
  • 118. Item 48: Avoid float and double if exact answers are required • The float and double types are designed primarily for scientific and engineering calculations. • The float and double types are particularly illsuited • for monetary calculations requiring exact answer because it is impossible to represent 0.1 as a float or double exactly. • Always use BigDecimal, int, or long for monetary calculations. • Disadvantage of using BigDecimal is that it is less convenient than using a primitive arithmetic type, and is slower. • An alternative to using BigDecimal is to use int or long, depending on the amounts involved.
  • 119. Item 49: Prefer primitive types to boxed primitives • Every primitive type has a corresponding reference type, called a boxed primitive. • The boxed primitives corresponding to int, double, and boolean are Integer, Double, and Boolean. • Primitives have only their values, whereas boxed primitives have identities distinct from their values. • Two boxed primitive instances can have the same value and different identities. • Primitive types have only fully functional values, whereas each boxed primitive type has one nonfunctional value, which is null, in addition to all of the functional values of its corresponding primitive type. • Primitives are generally more time and space-efficient than boxed primitives.