标签:line 异常 有一个 提示 界面 故障 src htm html
https://www.dubby.cn/detail.html?id=9033
本篇文章主要给大家介绍一些众所周知的异常处理原则,但是也有部分鲜为人知,但也很有用的原则,希望能引发各位对异常处理的思考,以及在开发过程中,写出更优美的代码。
大致可以把异常分成三种情况下的异常(不正常情况):
无图言屌,下面就给出异常的继承关系图:
主要说说这几个概念:
OutOfMemoryError
, LinkageError
, 还有StackOverflowError
。这种错误一般会是的程序(或者程序的一部分)不可用。针对这类错误,一定要有一个良好的日志习惯,不然很难定位。一般我们想要自定义异常的目的都是为了让异常信息更丰富,比如:输入名称不合法,我们可能希望有一个UsernameInvalidException
。本人在代码中曾经这么干过,一个类似的用法,好处很明显,在我们的内部监控系统中,对异常统计界面可以很清晰的反映出是什么问题,但是也带来一个问题,那就是异常数量很多。
在这里我先摆几个大师的意见吧:
IllegalStateException
UnsupportedOperationException
IllegalArgumentException
NoSuchElementException
NullPointerException
public class OutOfRangeException
extends IllegalArgumentException {
private final long value, min, max;
public OutOfRangeException(long value, long min, long max) {
super("Value " + value + " out of range " +
"[" + min + ".." + max + "]");
this.value = value;
this.min = min;
this.max = max;
}
public long getValue() {
return value;
}
public long getMin() {
return min;
}
public long getMax() {
return max;
}
}
catch (NoSuchMethodException e) {
return null;
}
这样做会让这个异常信息永远的丢失,你将无法知道这个异常的原因,怎么去解决这个异常,甚至你不知道有这个异常的存在。
public void foo() throws Exception { //不正确的做法
}
这样除了告诉调用方我可能会有异常之外没有任何其他信息,而事实是我们本可以提供更具体的信息,建议这样做:
public void foo() throws SpecificException1, SpecificException2 { //正确的做法
}
try {
someMethod();
} catch (Exception e) {
LOGGER.error("method has failed", e);
}
这么做的问题是,如果你调用的方法中多了一个新的异常,他本来的目的是希望你处理这个新的异常,可是因为你在这里捕获了所有的异常,你可能会忽略这个提醒,而忘记捕获。
这样会捕获本来不该有我们来处理的错误,包括一些我们的代码无法处理的错误。
catch (NoSuchMethodException e) {
throw new MyServiceException("Some information"); //不正确
}
这样做会完全丢失异常信息。
catch (NoSuchMethodException e) {
throw new MyServiceException("Some information: " + e.getMessage()); //不正确
}
这种做法会丢失堆栈信息,建议:
catch (NoSuchMethodException e) {
throw new MyServiceException("Some information: " , e); //正确
}
catch (NoSuchMethodException e) {
LOGGER.error("Some information", e);
throw e;
}
这样会导致一个问题,就是一个异常会有多份日志,因为上层可能也会记一次日志。所以要么上抛,要么记日志,不要都做。
try {
someMethod(); //Throws exceptionOne
} finally {
cleanUp(); //If finally also threw any exception the exceptionOne will be lost forever
}
这样的问题是,如果finally里也抛异常,就会导致真正的异常信息丢失,你只会收到finally里抛的异常。
catch (NoSuchMethodException e) {
throw e; //Avoid this as it doesn‘t help anything
}
这段代码没有任何有意义,你可以直接上抛。
这种输出没有任何意义,而且不确定输出路径,对定位问题没有帮助。
try {
someMethod(); //Method 2
} finally {
cleanUp(); //do cleanup here
}
如果你只是想要finally来做善后,那就只用它就可以了,不要用catch。
这句话我不想翻译,因为我希望你能看到这句话,以后你也会见到这句话的。Throw early catch late。在底层抛异常,在信息足够的时候来捕获并处理。
比如数据库连接,一定要用finally关闭连接。当然你也可以用try-with-resource的方式。
如果这个方法是解析文件,那么FileNotFoundException
就比NullPointException
更明确。
public void useExceptionsForFlowControl() {
try {
while (true) {
increaseCount();
}
} catch (MaximumCountReachedException ex) {
}
//Continue execution
}
public void increaseCount()
throws MaximumCountReachedException {
if (count >= 5000)
throw new MaximumCountReachedException();
}
算我求你了,不要这么干!
很多异常都是由不合法的输入引起的,所以尽可能早的校验输入。
LOGGER.debug("Using cache sector A");
LOGGER.debug("Using retry sector B");
何必呢?而且这样也容易误导其他人,建议:
LOGGER.debug("Using cache sector A, using retry sector B");
包括堆栈和其他提示信息。
while (true) {
try {
Thread.sleep(100000);
} catch (InterruptedException e) {} //Don‘t do this
doSomethingCool();
}
这段代码很cool,但是一般会interrupt线程,要么是超时了,要么是线程池被关闭了,所以你应该尽可能的去结束线程。
class DBUtil{
public static void closeConnection(Connection conn){
try{
conn.close();
} catch(Exception ex){
//Log Exception - Cannot close connection
}
}
}
使用这个来减少每次都try一遍。
/**
* This method does something extremely useful ...
*
* @param input
* @throws MyBusinessException if ... happens
*/
public void doSomething(String input) throws MyBusinessException { ... }
前人种树后人乘凉,你可能也可以乘凉。
标签:line 异常 有一个 提示 界面 故障 src htm html
原文地址:https://www.cnblogs.com/wxdlut/p/9102933.html