## Consider a builder when faced with many constructor parameters

wikipedia：JavaBeans

## Eliminate obsolete object references

An obsolete reference is simply a reference that will never be dereferenced again. Memory leaks in garbage-collected languages(known as unintentional object retentions) are insidious. If an object reference is unintentionally retained, not only is that object excluded from garbage collection, but so too are any objects referenced by that object, and so on.

The fix for this sort of problem is simple: null out references once they become obsolete. So, when object references should be nulled?

1. Nulling out object references 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. This occurs naturally if you define each variable in the narrowest possible scope.
2. Generally speaking, whenever a class manages its own memory, the programmer should be alert for memory leaks. Whenever an element is freed, any object references contained in the element should be nulled out.
3. Another commmon source of memory leaks is caches: once you put an object reference into a cache, it’s easy to forget that it’s there and leave it in the cache long after it becomes irrelevant.
4. A third common source of memory leaks is listeners and callbacks: if you implement an API where clients register callbacks but don’t deregister them explicitly, they will accumulate unless you take some action.

## Obey the general contract when overriding equals

2. 不用关心类是否提供了“逻辑相等”测试：比如java.util.Random类并不需要重载equals方法来检测两个实例是否相同；
3. 父类已经重载了equals，而且该方法同样适用于这个类时，不用再重载；
4. 类时私有的或者包私有的，并且可以确定equals方法不会被调用，则不用重载。

1. 反射性(reflexive): 对任何非NULL引用 x, x.equals(x)必须为真；
2. 对称性(symmetric): 对任何非NULL引用 x,y: 当且仅当x.equals(y)返回真时，y.equals(x)才为真；
3. 传递性(transitive): 对任何非NULL引用x,y,z,如果x.equals(y)y.equals(z)均为真，则x.equals(z)也为真；
4. 一致性(consisitency): 如果两个非NULL引用x,y相等，那么应该一直相等除非有一个被改变了；
5. 空值行(Non-nullity): 对于任何非NULL引用 x，x.equals(NULL)为假；

## Always override hashCode when you override equals

1. 将一个int型变量 result 初始化为一个非零值，比如17；
2. 对于类中不同类型的成员变量，其相应的hash值 c 如下：

• boolean: c = (f ? 0 : 1)
• byte, char,short, or int: c = (int) f
• long: c = (int) (f ^( f >>> 32))
• float: c = Float.floatToIntBits(f)
• double: long l = Double.doubleToLongBits(f);c = (int)(1^(l >>> 32))
• Object: c = f.hashCode()
• Array: 应用上述规则
• 将所得hash值计算存入result: result = 31 * result + c;
3. 返回结果；并确保两个相等(equals)的对象是否有相同的hash值；

## Mininmize mutability

1. 不要提供修改对象状态的任何接口(mutators);
2. 确保类不可扩展(extend)：防止类被子类化的简单办法是将其声明为final;或者将其构造函数都声明为private，紧急只提供一个静态的工厂方法来产生类的对象；
3. 将所有成员变量声明为final
4. 将所有成员声明为private
5. 有可变的成员变量时，确保其不可被外部修改；

## Prefer interfaces to abstract classes

It is far easier to evolve an abstract class than an interface(once an interface is released and widely implemented, it is almost impossible to change);

In summary, an interface is generally the best way to define a type that permits multiple implementations. An exception to this rule is the case where ease of evolution is deemed more important than flexibility and power.

## Favor static member classes over nonstatic

If you declare a member class that doesnot require access to an enclosing instance, always put the static modifier in its declaration.

## Do not use raw types in new code

Using raw types can lead to exceptions at runtime, so don’t use them in new code.

You must use raw types in class literals: List.class,String[].class,and int.class are all legal,but List<String>.classList<?>.class are not

## Design Method signatures carefully

1. 谨慎的命名方法：命名始终遵循标准的命名约定，首要的目标应该是确保命名是可被理解，并且与包内其他命名保持一致；
2. 不要提供太多的方法： 方法太多容易使类变得难以学习，使用，编写文档，测试跟维护，这个对于interface来说尤其如此。因此，当存疑时，应该直接忽略；
3. 避免过长的参数列表：保持四个或者更少的参数。怎么减少参数？有三个办法：一个是将该方法分解为几个不同的方法，每个方法只包含一部分参数；第三个方法是使用Builder模式
4. 对于参数类型来说，使用interface而不是classes；
5. 尽量使用两个元素的enum类型而非boolean参数，让程序变得更具可读性；

## Optimize judiciously

M.A.Jackson: we follow two rules in the matter of optimization:

• Rule 1. Don’t do it;
• Rule 2. (for experts only). Don’t do it yet - that is,not until you have a perfectly clear and unoptimized solution.

## Use checked exceptions fo recoverable conditions and runtime exceptions for programming errors

Java语言提供了三类可抛出对象(throwables):可检查的异常，运行时异常，以及错误。对于客户端需要从异常中恢复的情况，应该使用可检查的异常；而对于编程错误（如客户端调用接口有误）则使用运行时异常。