Notes: Effective Java: Exceptions

Notes from the book Effective Java by Joshua Bloch (http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)

Use exceptions only for exceptional conditions.

Use checked exceptions for recoverable conditions and runtime exceptions for programming errors.

Avoid unnecessary use of checked exceptions.

Favor the use of standard exceptions.

Throw exceptions appropriate to the abstraction
A higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction. This idiom is known as exception translation:

Exception Translation

try {
	// Use lower-level abstraction to do our bidding
	...
	} catch(LowerLevelException e) {
		throw new HigherLevelException(...);
}

Document all exceptions thrown by each method.

Include failure-capture information in detail messages

Strive for failure atomicity
After an object throws an exception, it is generally desirable that the object still be in a well-defined, usable state, even if the failure occurred in the midst of performing an operation. This is especially true for checked exceptions, from which the caller is expected to recover. Generally speaking, a failed method invocation should leave the object in the state that it was in prior to the invocation. A method with this property is said to be failure atomic.
There are several ways to achieve this effect. The simplest is to design immutable objects.
For methods that operate on mutable objects, the most common way to achieve failure atomicity is to check parameters for validity before performing the operation.
A closely related approach to achieving failure atomicity is to order the computation so that any part that may fail takes place before any part that modifies the object.
A final approach to achieving failure atomicity is to perform the operation on a temporary copy of the object and to replace the contents of the object with the temporary copy once the operation is complete.

Don’t ignore exceptions

Notes: Effective Java: General Programming

Notes from the book Effective Java by Joshua Bloch (http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)

Minimize the scope of local variables

○ The most powerful technique for minimizing the scope of a local variable is to declare it where it is first used.
○ Nearly every local variable declaration should contain an initializer.

Prefer for-each loops to traditional for loops

In summary, the for-each loop provides compelling advantages over the traditionalfor loop in clarity and bug prevention, with no performance penalty. You should use it wherever you can. Unfortunately, there are three common situations where you can’t use a for-each loop:
○ 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 (as demonstrated unintentionally in the buggy card and dice examples above).

Avoid float and double if exact answers are required
Use BigDecimal, int, or long for monetary calculations.

Prefer primitive types to boxed primitives

Broken comparator – can you spot the flaw?

Comparator<Integer> naturalOrder = new Comparator<Integer>() {
	public int compare(Integer first, Integer second) {
		return first < second ? -1 : (first == second ? 0 : 1);
	}
};

Applying the == operator to boxed primitives is almost always wrong.

public class Unbelievable {
	static Integer i;
	public static void main(String[] args) {
		if (i == 42)
			System.out.println("Unbelievable");
	}
}

The class thows NullPointerException as we are trying to unbox Interger I which was assigned a default value of null when it was declared.

Hideously slow program! Can you spot the object creation?

public static void main(String[] args) {
	Long sum = 0L;
	for (long i = 0; i < Integer.MAX_VALUE; i++) {
		sum += i;
	}
	System.out.println(sum);
}

Notes: Effective Java: defensive copies

Notes from the book Effective Java by Joshua Bloch (http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)

Broken “immutable” time period class

public final class Period {
	private final Date start;
	private final Date end;
	/**
	* @param  start the beginning of the period
	* @param  end the end of the period; must not precede start
	* @throws IllegalArgumentException if start is after end
	* @throws NullPointerException if start or end is null
	*/
	public Period(Date start, Date end) {
		if (start.compareTo(end) > 0){
			throw new IllegalArgumentException(start + " after " + end);
		}
		this.start = start;
		this.end   = end;
	}
	public Date start() {
		return start;
	}
	public Date end() {
		return end;
	}
	... // Remainder omitted

}

Attack the internals of a Period instance

Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
end.setYear(78);  // Modifies internals of p!

Repaired constructor – makes defensive copies of parameters

public Period(Date start, Date end) {
	this.start = new Date(start.getTime());
	this.end   = new Date(end.getTime());
	
	if (this.start.compareTo(this.end) > 0){
		throw new IllegalArgumentException(this.start + " after " + this.end);
	}
}

Note that defensive copies are made before checking the validity of the parameters, and the validity check is performed on the copies rather than on the originals. While this may seem unnatural, it is necessary. It protects the class against changes to the parameters from another thread during the “window of vulnerability” between the time the parameters are checked and the time they are copied. (In the computer security community, this is known as a time-of-check/time-of-use or TOCTOU attack

Do not use the clone method to make a defensive copy of a parameter whose type is subclassable
by untrusted parties.

Second attack on the internals of a Period instance

Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
p.end().setYear(78);  // Modifies internals of p!

To defend against the second attack, merely modify the accessors to return defensive copies of mutable internal fields:
Repaired accessors – make defensive copies of internal fields

public Date start() {
	return new Date(start.getTime());
}
public Date end() {
	return new Date(end.getTime());
}

Defensive copying of parameters is not just for immutable classes. Anytimeyou write a method or constructor that enters a client-provided object into an internal data structure, think about whether the client-provided object is potentially mutable. If it is, think about whether your class could tolerate a change in the object after it was entered into the data structure. If the answer is no, you must defensively copy the object and enter the copy into the data structure in place of the original. For example, if you are considering using a client-provided object reference as an element in an internal Set instance or as a key in an internal Map instance, you should be aware that the invariants of the set or map would be
destroyed if the object were modified after it is inserted.

The same is true for defensive copying of internal components prior to returning them to clients. Whether or not your class is immutable, you should think twice before returning a reference to an internal component that is mutable. Chances are, you should return a defensive copy. Remember that nonzero-length arrays are always mutable. Therefore, you should always make a defensive copy of an internal array before returning it to a client. Alternatively, you could return an immutable view of the array. Both of these techniques are shown in Item 13.

Arguably, the real lesson in all of this is that you should, where possible, use immutable objects as components of your objects, so that you that don’t have to worry about defensive copying (Item 15). In the case of our Period example, it is worth pointing out that experienced programmers often use the primitive long returned by Date.getTime() as an internal time representation instead of using a Date reference. They do this primarily because Date is mutable.

In summary, if a class has mutable components that it GETS FROM or RETURNS TO its clients, the class must defensively copy these components.

Notes: Effective Java: Check method parameters for validity

Notes from the book Effective Java by Joshua Bloch (http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)

Check method parameters for validity.

I am adding this one liner note as a separate post because of the sheer number of times I have asked my colleagues and of course the rubber duck to follow this advice.

Notes: Effective Java: Use enums instead of int constants

Notes from the book Effective Java by Joshua Bloch (http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)

The basic idea behind Java’s enum types is simple: they 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. Because clients can neither create instances of an enum type nor extend it, there can be no instances but the declared enum constants. In other words, enum types are instance-controlled (page 6). They are a generalization of singletons (Item 3), which are essentially single-element enums.

Enums provide compile-time type safety. If you declare a parameter to be of type Apple, you are guaranteed that any non-null object reference passed to the parameter is one of the three valid Apple values. 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 because each type has its own namespace.

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 (Item 15). They can be public, but it is better to make them private and provide public accessors (Item 14).

// Enum type with data and behavior
public enum Planet {
	MERCURY(3.302e+23, 2.439e6),
	VENUS (4.869e+24, 6.052e6),
	EARTH (5.975e+24, 6.378e6),
	
	private final double mass;           // In kilograms
	private final double radius;         // In meters
	private final double surfaceGravity; // In m / s^2
	
	// Universal gravitational constant in m^3 / kg s^2
	private static final double G = 6.67300E-11;
	
	// Constructor
	Planet(double mass, double radius) {
		this.mass = mass;
		this.radius = radius;
		surfaceGravity = G * mass / (radius * radius);
	}
	
	public double mass()           { return mass; }
	public double radius()         { return radius; }
	public double surfaceGravity() { return surfaceGravity; }
	public double surfaceWeight(double mass) {
		return mass * surfaceGravity; // F = ma
	}
}

Enums can have overridden behaviors. For example a fruit enum constant APPLE may return a different value from colorOfFruitMethod() than the one returned by enum constant ORANGE.

// Enum type with constant-specific method implementations
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;} };
	
	abstract double apply(double x, double y); 
}

Abstract methods in an enum type must be overridden with concrete methods in ALL of its constants.
So a strategy can be implemented for enums constants as below:

// The strategy enum pattern
enum PayrollDay {
	MONDAY(PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY),  WEDNESDAY(PayType.WEEKDAY), THURSDAY(PayType.WEEKDAY), FRIDAY(PayType.WEEKDAY), SATURDAY(PayType.WEEKEND),  SUNDAY(PayType.WEEKEND); 
	
	private final PayType payType;
	
	PayrollDay(PayType payType) {this.payType = payType; } //Constructor with strategy.
	
	double pay(double hoursWorked, double payRate) {
		return  this.payType.pay(hoursWorked, payRate);          //Use of strategy
	}
	// The strategy enum type
	private enum PayType {
		WEEKDAY { double overtimePay(double hours, double payRate) {
			return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT) * payRate / 2;
		} },
		WEEKEND {double overtimePay(double hours, double payRate) {
			return hours * payRate / 2;
		}};
		private static final int HOURS_PER_SHIFT = 8;
		abstract double overtimePay(double hrs, double payRate);
		double pay(double hoursWorked, double payRate) {
			double basePay = hoursWorked * payRate;
			return basePay + overtimePay(hoursWorked, payRate);
		}
	}
}

In summary, enums are far more readable, safer, and more powerful. Many enums require no explicit constructors or members, but many others benefit from associating data with each constant and providing methods whose behavior is affected by this data. Far fewer enums benefit from associating multiple behaviors with a single method. In this relatively rare case, prefer constant-specific methods to enums that switch on their own values. Consider the strategy enum pattern if multiple enum constants share common behaviors.

Notes: Effective Java: Use bounded wildcards to increase API flexibility

Notes from the book Effective Java by Joshua Bloch (http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)

Wildcard type for parameter that serves as an E producer
src parameter produces E instances for use by the Stack

public void pushAll(Iterable<? extends E> src) {
for (E e : src)
	push(e);
}

Wildcard type for parameter that serves as an E consumer
dst parameter consumes E instances from the Stack

//(while stack is not empty pop a element from the stack and store it into a collection dst)
public void popAll(Collection&amp;lt;? super E&amp;gt; dst) {
	while (!isEmpty())
		dst.add(pop());
}

The lesson is clear. 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 you no good: you need an exact type match, which is what you get without any wildcards.

Here is a mnemonic to help you remember which wildcard type to use:

PECS

PECS stands for producer-extends, consumer-super.

In other words, if a parameterized type represents a T producer, use <?extendsT>;  if it represents a T consumer, use <?superT>. In our Stack example, pushAll’s src parameter produces E instances for use by the Stack, so the appropriate type for src is Iterable<?extendsE>;popAll’s dst parameter consumes E instances from the Stack, so the appropriate type for dst is Collection<?superE>. The PECS mnemonic captures the fundamental principle that guides the use of wildcard types. Naftalin and Wadler call it the Get and Put Principle.

 

The Get and Put Principle: use an extends wildcard when you only get values out of a structure, use a super wildcard when you only put values into a structure, and don’t use a wildcard when you both get and put.

 

Notes: Effective Java: Favor generic types and methods

Notes from the book Effective Java by Joshua Bloch (http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)

It is generally not too difficult to parameterize your collection declarations and make use of the generic types and methods provided by the JDK. Writing your own generic types is a bit more difficult, but it’s worth the effort to learn how.

Favor generic methods

Just as classes can benefit from generification, so can methods. Static utility methods are particularly good candidates for generification. All of the “algorithm” methods in Collections (such as binarySearch and sort) have been generified.

For example,

// Generic method
public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
	Set<E> result = new HashSet<E>(s1);
	result.addAll(s2);
	return result;
}

// Parameterized type instance creation with constructor
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

To eliminate this redundancy, write a generic static factory method corresponding to each constructor that you want to use. For example, here is a generic static factory method corresponding to the parameterless HashMap constructor:


// Generic static factory method
public static <K,V> HashMap<K,V> newHashMap() {
	return new HashMap<K,V>();
}

With this generic static factory method, you can replace the repetitious declaration above with this concise one:


// Parameterized type instance creation with static factory
Map<String, List<String>> anagrams = newHashMap();