编码约定
1.考虑将状态不变的类声明为final,如:
public final class BitSet ... {
public BitSet() {...}
public BitSet(int) {...}
public void set(int) {...}
public boolean get(int) {...}
public int size() {...}
}
2.定义更小的类和方法
3.定义子类使之可以父类使用的任何地方使用,可以使用开放-关闭原则(对扩展开放,对修改关闭)设计父类和子类
4.使所有成员变量私有
5.使用多态来替代instanceof,更安全的做法
类型安全
1.以操作java.lang.Object来包装通用类,提供静态类型检查
public class Queue {
public void enqueue(Object object) {...};
public Object dequeue() {...};
}
public class OrderQueue {
private Queue queue;
public OrderQueue()
this.queue = new Queue();
}
public void enqueue(Order order) {
this.queue.enqueue(order);
}
public Order dequeue() {
return (Order)this.queue.dequeue();
}
}
2.以类的形式来封装枚举类型
表达式
1.使用相当的方法来替换重复出现的、有点复杂的表达式。分解出常见的功能,并重新包装为方法或类
2.使用块状语句来替代控制流结构的表达式
for (int i = n;i >= 0;i--) {
for (int j = n;j >= 0;j--) {
f(i,j);
g(i,j); // Can add here!
}
}
3.使用括号明确运算顺序
// Extraneous but useful parentheses.
int width = (( buffer * offset ) / pixelWidth )+ gap;
4.在switch语句最后一个case中总是键入Break语句
5.使用equals()而不是==来测试对象的相等性
构造函数
1.不要在构造函数中调用非final方法
2.使用嵌套构造函数来消除冗余代码
class Account {
String name;
double balance;
final static double DEFAULT_BALANCE = 0.0d;
Account(String name, double balance) {
this.name = name;
this.balance = balance;
}
Account(String name) {
this(name, DEFAULT_BALANCE);
}
}
异常处理
1.使用不需检查运行时异常来报告严重的、无法预期的错误,这可能指出程序逻辑中的错误。
2.使用需检查异常来报告可能发生但是在正常程序操作中很难发生的错误
3.使用return代码来报告期望的状态改变。
4.仅以增加信息形式来改变异常。保留所有的异常信息
try {
for(int i = v.size();--i >= 0;) {
ostream.println(v.elementAt(i));
}
}catch (ArrayOutOfBounds e) {
// should never get here
throw new UnexpectedExceptionError(e);
}
5.不要略去运行时或错误异常
6.使用finally块以释放资源
断言
1.编程遵守约定
prepend(Object object) {
// Test pre-condition
if (Assert.ENABLED)
Assert.isTrue(object != null);
doPrepend(object);
// Test post-condition
if (Assert.ENABLED)
Assert.isTrue(first() == object);
}
2.使用断言捕获代码中的逻辑错误
3.在任何一个合适的公开方法使用断言测试方法的前置和后置条件
并发
1.仅在适当时使用线程
- 同时对多个事件作出反应
例子 ︰ 互联网浏览器或服务器。
- 提供高水平的响应能力。
示例 ︰ 用户界面执行可以继续对用户操作做出响应,尽管应用程序的执行其他计算。
- 如果要充分利用具有多个处理器的机器。
示例 ︰ 针对特定的计算机体系结构的应用程序。
同步
1.避免同步
2.使用同步包装来提供同步接口
public class Stack {
public void push(Object o) {...};
public Object pop() {...};
public static Stack createSynchronizedStack() {
return new SynchronizedStack();
}
}
class SynchronizedStack extends Stack {
public synchronized void push(Object o) {
super.push(o);
}
public synchronized Object pop() {
return super.pop();
}
}
3.如果方法包含几个不需要同步的重要步骤,那么不要同步整个方法,使用同步代码块
4.当读写实例变量时避免不必要的同步
5.考虑用notify()替代notifyAll()
6.对于同步的初始化应使用双重检查模式
Log getLog() {
if (this.log==null) {
synchronized (this) {
if (this.log==null) {
this.log = new Log();
}
}
}
return this.log;
}
效率
1.使用延迟初始化,类的对象如果不需要马上使用就不需要马上来创建
class PersonalFinance {
LoanRateCalculator loanCalculator = null;
LoanRateCalculator getLoanCalculator() {
if (this.loanCalculator == null)
this.loanCalculator =new LoanRateCalculator();
return this.loanCalculator;
}
}
2.避免创建不必要的对象
3.重复初始化和重复使用对象以避免创建新的对象,可以使用工厂模式来负责对象的创建
4.留待以后优化,如果你真的需要去优化代码的时候再去做
包约定
1.把经常使用、变化和发布或者彼此互相依赖的的类放置在相同的包中
2.将volatile类和接口隔离在单独的包中
3.避免创建的包,依赖于经常变化的包,使其很难变化
4.最大的抽象化以达到最大的稳定性
5.采用高水平的设计和架构使包保持稳定