Item 3: Enforce the singleton property with a private constructor or an enum type
To maintain the singleton guarantee, declare all instance fields transient and provide a readResolve method .
// readResolve method to preserve singleton property
private Object readResolve() {
// Return the one true Elvis and let the garbage collector
// take care of the Elvis impersonator.
return INSTANCE;
}
Item 26: Don’t use raw types
主要是把Java泛型的一些细节过下,这篇文章不错:Java泛型详解。
Item 31: Use bounded wildcards to increase API flexibility
PECS stands for producer-extends, consumer-super.
最典型的就是max()这个方法:
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll){}
Item 34: Use enums instead of int constants
public enum Operation {
PLUS {
public double apply(double x, double y) {return x + y;}
},
MINUS {
public double apply(double x, double y) {return x - y;}
},
TIMES {
public double apply(double x, double y) {return x * y;}
},
DIVIDE {
public double apply(double x, double y) {return x / y;}
};
public abstract double apply(double x, double y);
}
可以通过编译、反编译看出这些enum成员的具体实现是啥机制。
Item 41: Use marker interfaces to define types
Item 60: Avoid float and double if exact answers are required
In summary, don’t use float or double for any calculations that require an exact answer. Use BigDecimal if you want the system to keep track of the decimal point and you don’t mind the inconvenience and cost of not using a primitive type.
Item 76: Strive for failure atomicity
public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference return result;
}
要注意不能因为中间步骤抛异常导致类状态不一致,其实这种类型的保证难度较大。
Item 78: Synchronize access to shared mutable data
17.7. Non-Atomic Treatment of `double` and `long`
非volatile的long和double不是原子的。
Synchronization is required for reliable communication between threads as well as for mutual exclusion.
其实synchronized
除了互斥之外,另外一个重要的作用是保证线程间的可见性。
Item 79: Avoid excessive synchronization
In summary, to avoid deadlock and data corruption, never call an alien method from within a synchronized region.
下面是stackoverflow上面一个很典型的死锁例子:
Java deadlock question
public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s has bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s has bowed back to me!%n",
this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alphonse = new Friend("Alphonse");
final Friend gaston = new Friend("Gaston");
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}