1、异常只用在不正常的情况下,不要用作正常的控制流。比如
public void goodExample(String[] strs) {
for (int i = 0; i < strs.length; i++) {
String str = strs[i];
}
}
public void badExample(String[] strs) {
try {
int i = 0;
while (true) {
String str = strs[i++];
}
} catch (IndexOutOfBoundsException e) {
;
}
}
原因:
1)异常是被设计来用在非正常情况下的;
2)性能差;
3)代码可读性差。
2、尽量使用标准的异常(而不是自定义异常)
好处:
- 代码重用;
- 可读性比较好,代码里不会充斥着程序员不熟悉的异常类;
- 异常类越少,意味着占用内存越少,并且加载类的时间开销也就越小。
使用下面常用的运行时异常,而不是新建新的异常类。
IllegalStateException
IllegalArgumentException
UnsupportedOperationException
IndexOutOfBoundsException
NullPointerException
ConcurrentModificationException
3、利用javadoc的@throws记录下方法可能抛出的异常(包括被检查异常和运行时异常)以及出现异常的条件。
比如:
/**
* Returns the first element in this list.
*
* @return the first element in this list
* @throws NoSuchElementException if this list is empty
*/
public E getFirst() {
if (size==0)
throw new NoSuchElementException();
return header.next.element;
}
4、抛出的异常要适合于相应的抽象
异常转译(Exception Translation):高层捕捉到低层异常,同时抛出按照高层规范来抽象的异常。
异常链接(Exception Chain):高层捕捉到低层异常,同时抛出按照高层规范来抽象的异常,并保存低层异常。
5、不要一概而论
我们经常会见到这样的代码:
try{
... ...
}catch(Exception e){
e.printStackTrace();
}
或
throw new Exception()
这样的问题是:不清楚错误原因在哪里,调用方无法根据错误类型做相应的处理。