Gruppe GrønGruppe Grøn
Effective JavaItems: 4, 12, 20, 28 36, 44, 52, 60
1
Item 4 Item 4 Enforce noninstantiability with a private Enforce noninstantiability with a private
constructorconstructor
Classes that just group static methods and static fields should not be instantiated
Such classes can be useful -- static methods, including factory methods, implementing an interface, for example
Not designed to be instantiated; instance wouldn’t make sense
2
Providing no constructor doesn’t work◦ If no explicit constructors, compiler provides
a public, parameterless default constructor
◦Looks just like any other constructor to clients
◦Allows for unintentionally instantiable classesMaking a class abstract doesn’t work
◦Class can be subclassed and subclass can be instantiated
◦Also misleads user into thinking class was designed for inheritance
Item 4 Item 4 Enforce noninstantiability with a private Enforce noninstantiability with a private
constructorconstructor
3
Including a private constructor does work◦A default constructor is generated
only if a class contains no explicit constructors
// Noninstantiable utility class
public class UtilityClass {
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
Item 4 Item 4 Enforce noninstantiability with a private Enforce noninstantiability with a private
constructorconstructor
4
Constructor is private, so inaccessible outside of class
AssertionError not necessary, but flags accidental invocation of constructor from inside class
Comment helpful since usage counterintuitive
Also prevents class from being subclassed◦All constructors must invoke a
superclass constructor◦No accessible superclass constructor
Item 4 Item 4 Enforce noninstantiability with a private Enforce noninstantiability with a private
constructorconstructor
5
Item 12 Item 12 Consider implementing ComparableConsider implementing Comparable
Comparable is an interface in java.lang package.◦It has only one method: compareTo()
that compares specific fields of two objects to determine if it is: less than equal to greater than the other object.
◦It throws ClassCastException if there is a type mismatch.
6
Comparable is useful when:◦ designing a class with natural
ordering of its instances fx age.◦When comparing objects of same
class according to specified criteria◦Sorting of objects into collection
framework(Arrays, TreeSet etc.)
Item 12 Item 12 Consider implementing ComparableConsider implementing Comparable
7
Example of a person class that implement comparable
import java.lang.*;
// in this example person objects will be compared according to their age
public class Person implements Comparable{
String name;
int age;
Person(...){...}
public int compareTo(Object o){
Person pe = (Person)o;
// compares age
if (age < pe.age)
return -1;
if (age > pe.age)
return 1;
return 0;
}
}
Item 12 Item 12 Consider implementing ComparableConsider implementing Comparable
8
compareTo() vs. equals()All objects have both identity (the object's location in memory) and state (the object's data)
The equals method operator tests for Identity equality/inequality
The CompareTo method operator tests for If this object is 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.The CompareTo method is similar to equals but needs to satisfy the following
conditions: anticommutation :
x.compareTo(y) is the opposite sign of y.compareTo(x)
exception symmetry : x.compareTo(y) throws exactly the same exceptions as y.compareTo(x)
transitivity : if x.compareTo(y)>0 and y.compareTo(z)>0, then x.compareTo(z)>0 (and same for less than) if x.compareTo(y)==0, then x.compareTo(z) has the same sign as y.compareTo(z)
consistency with equals is highly recommended, but not required : x.compareTo(y)==0, if and only if x.equals(y) ; consistency with equals is required for ensuring
sorted collections (such as TreeSet) are well-behaved.
Item 12 Item 12 Consider implementing ComparableConsider implementing Comparable
9
Item 12 Item 12 Consider implementing ComparableConsider implementing Comparable
Person(...){...} public int compareTo(Object o){ Person pe = (Person)o; return age - pe.age; }}
10
Generic types are invariant◦ That is, List<String> is not a subtype of List<Object>◦ Good for compile-time type safety, but inflexible
Bounded wildcard types provide additional API flexibilty
Item 28 Item 28 Use bounded wildcards to increase API flexibilityUse bounded wildcards to increase API flexibility
11
PECS
◦ Producer extends
◦ Consumer super
For a T producer, use Foo<? extends T>
For a T consumer, use Foo<? super T>
Only applies to input parameters
◦Don’t use wildcard types as return
types
Item 28 Item 28 Use bounded wildcards to increase API flexibilityUse bounded wildcards to increase API flexibility
12
PECS in Action (1) Suppose you want to add bulk methods to Stack<E>
void pushAll(Collection<E> src);
void popAll(Collection<E > dst);
Item 28 Item 28 Use bounded wildcards to increase API flexibilityUse bounded wildcards to increase API flexibility
13
PECS in Action (1) Suppose you want to add bulk methods to Stack<E>
void pushAll(Collection<? extends E> src);
◦ src is an E producer
void popAll(Collection<E> dst);
Item 28 Item 28 Use bounded wildcards to increase API flexibilityUse bounded wildcards to increase API flexibility
14
PECS in Action (1) Suppose you want to add bulk methods to Stack<E>
void pushAll(Collection<? extends E> src);
◦ src is an E producer
void popAll(Collection<? super E> dst);
◦ dst is an E consumer
Item 28 Item 28 Use bounded wildcards to increase API flexibilityUse bounded wildcards to increase API flexibility
15
PECS in Action (1) Suppose you want to add bulk methods to Stack<E>
void pushAll(Collection<? extends E> src);
void popAll(Collection<? super E> dst);
User can pushAll from a Collection<Long> or a Collection<Number> onto a Stack<Number>
User can popAll into a Collection<Object> or a Collection<Number> from a Stack<Number>
Item 28 Item 28 Use bounded wildcards to increase API flexibilityUse bounded wildcards to increase API flexibility
16
PECS in Action (2)Consider this generic method:
public static <E> Set<E> union(Set<E> s1,
Set<E> s2)
Item 28 Item 28 Use bounded wildcards to increase API flexibilityUse bounded wildcards to increase API flexibility
17
PECS in Action (2)Consider this generic method:
public static <E> Set<E> union(Set<? extends E> s1, Set<? extends E> s2)
Both s1 and s2 are E producers No wildcard type for return value
◦ Wouldn’t make the API any more flexible◦ Would force user to deal with wildcard
types explicitly◦ User should not have to think about
wildcards to use your API
Item 28 Item 28 Use bounded wildcards to increase API flexibilityUse bounded wildcards to increase API flexibility
18
Item 60 Item 60 Favor the use of standard Favor the use of standard
exceptionsexceptions
Exceptions: code reuse is good.The Java platform libraries provide
a basic set of unchecked exceptions
Benefits of using preexisting:◦API is easier to learn and use◦Is easier to read◦fewer exception classes mean a
smaller memory footprint and less time spent loading classes
19
Item 60 Item 60 Favor the use of standard Favor the use of standard
exceptionsexceptions
all erroneous method invocations boil down to an illegal argument or illegal state
20
Item 60 Item 60 Favor the use of standard Favor the use of standard
exceptionsexceptions
Others:◦ArithmeticException◦NumberFormatException
If an exception fits your needs, go ahead and use it
choosing which exception to reuse is not always an exact science
21
Use interfaces rather than classes as parameter types
If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface types.// Good – uses interface as typeList<Subscriber> subscribers = new Vector<Subscriber>();// Bad – uses class as typeVector<Subscriber> subscribers = new
Vector<Subscriber>();List is an interface and Vector is an implementation of the
List interface
Item 52 Item 52 Refer to objects by their interfacesRefer to objects by their interfaces
22
Item 52 Item 52 Refer to objects by their interfacesRefer to objects by their interfaces
• If you get into the habit of using interfaces as types, your program will be much more flexible.
• To switch implementations, change the class name in the constructor
List<Subscriber> subscribers = new ArrayList<Subscriber>();
And all the surrounding code continues to work!
23
The most important annotation is @Override
It can only be used on method declarations, and indicates override of a supertype
Item 36 Item 36 Consistently use the Override annotationConsistently use the Override annotation
24
public boolean equals(Bigram b) {return b.first == first && b.second == second;}
To override Object.equals, you must define an equals method whose parameter is of type Object
Bigram is not of type Object and to find errors like that annotations like @Overrides helps the compiler to generate a message like this:Bigram.java:10: method does not override or implement a method
from a supertype
@Override public boolean equals(Bigram b)
Item 36 Item 36 Consistently use the Override annotationConsistently use the Override annotation
25
Replace the implementation with this:
@Override
public boolean equals(Object o) {
if(!(o instanceof Bigram))
return false;
Bigram b = (Bigram)o;
return b.first == first && b.second == second;
}
Item 36 Item 36 Consistently use the Override annotationConsistently use the Override annotation
26
@Overrides provides help in finding bugs
In abstract class or an Interface it is worth annotating all methods believed to override superclass or superinterface methods.
In concrete classes its not needed to annotate methods that are belived to override abstract method declarations.
Item 36 Item 36 Consistently use the Override annotationConsistently use the Override annotation
27
The Javadoc utility translates doc comments into HTML◦{@code} has two purposes
It causes the code fragment to be rendered in code font
And it suppresses processing of HTML markups and nested Javadoc tags in the code fragment (the less than sign <) even though it is an HTML metacharacter.
Item 44 Item 44 Write doc comments for all exposed APIWrite doc comments for all exposed API
28
To generate documentation containing HTML metacharacters (<> and &) the best way is to surround them with◦{@literal} it is like the {@code}
tag but doesnt render the text in code font.
• The triangle inequality is {@literal |x + y| < |x| + |y|}.
• Outcome “The triangle inequality is |x + y| < |x| + |y|.”
Item 44 Item 44 Write doc comments for all exposed APIWrite doc comments for all exposed API
29
A class whose instances come in two or more and contain a tag field indicating the flavor of the instance.
class Figure {
enum Shape { RECTANGLE, CIRCLE };
final Shape shape; // Tag field - the shape of this figure
double length, width; // These fields are used only if shape is RECTANGLE
double radius; // This field is used only if shape is CIRCLE
Figure(double radius) {shape = Shape.CIRCLE; this.radius = radius;} // Constructor for circle
Figure(double length, double width) {shape = Shape.RECTANGLE; this.length = length; this.width = width;} // Constructor for
rectangle
double area() {switch(shape) {
case RECTANGLE:return length * width;
case CIRCLE:return Math.PI * (radius * radius);
default:
throw new AssertionError();
}
}
Item 20 Item 20 Prefer class hierarchies to tagged classesPrefer class hierarchies to tagged classes
30
Tagged classes are:Error-prone, verbose and
inefficient.Instances are burdened with
irrelevant fields belonging to other flavors of same instance (circle and square)
Constructors must set tag fields and initialize the right data fields with no help form the compiler
Item 20 Item 20 Prefer class hierarchies to tagged classesPrefer class hierarchies to tagged classes
31