什么是Stacktrace?
stacktrace是一个非常有用的调试工具。它显示了抛出未捕获异常时(或手动生成堆栈跟踪的时间)的调用堆栈(即,到那时为止调用的函数的堆栈)。这是非常有用的,因为它不仅显示了错误发生的位置,而且还显示了程序是如何在代码的那个位置结束的。
这就引出了下一个问题:
什么是异常?
异常是运行时环境用来告诉您发生错误的东西。流行的例子是NullPointerException, IndexOutOfBoundsException或arithmeexception。这些都是当你试图做一些不可能的事情时造成的。例如,当你试图解引用一个null对象时,会抛出一个NullPointerException:
Object a = null;
a.toString(); //this line throws a NullPointerException
Object[] b = new Object[5];
System.out.println(b[10]); //this line throws an IndexOutOfBoundsException,
//because b is only 5 elements long
int ia = 5;
int ib = 0;
ia = ia/ib; //this line throws an ArithmeticException with the
//message "/ by 0", because you are trying to
//divide by 0, which is not possible.
我应该如何处理stacktrace /异常?
首先,找出导致异常的原因。尝试在谷歌上搜索异常的名称,以找出该异常的原因。大多数情况下,它是由错误的代码引起的。在上面给出的例子中,所有的异常都是由错误的代码引起的。所以对于NullPointerException的例子,你可以确保a在那个时候永远不为空。例如,你可以初始化一个或包含一个检查,就像这样:
if (a!=null) {
a.toString();
}
这样,如果a==null,就不会执行出错的行。其他例子也一样。
Sometimes you can't make sure that you don't get an exception. For example, if you are using a network connection in your program, you cannot stop the computer from loosing it's internet connection (e.g. you can't stop the user from disconnecting the computer's network connection). In this case the network library will probably throw an exception. Now you should catch the exception and handle it. This means, in the example with the network connection, you should try to reopen the connection or notify the user or something like that. Also, whenever you use catch, always catch only the exception you want to catch, do not use broad catch statements like catch (Exception e) that would catch all exceptions. This is very important, because otherwise you might accidentally catch the wrong exception and react in the wrong way.
try {
Socket x = new Socket("1.1.1.1", 6789);
x.getInputStream().read()
} catch (IOException e) {
System.err.println("Connection could not be established, please try again later!")
}
为什么我不应该使用catch(例外e)?
让我们用一个小例子来说明为什么不应该捕获所有异常:
int mult(Integer a,Integer b) {
try {
int result = a/b
return result;
} catch (Exception e) {
System.err.println("Error: Division by zero!");
return 0;
}
}
这段代码试图做的是捕获由可能的除0引起的ArithmeticException。但它也捕获一个可能的NullPointerException,如果a或b为空则抛出该异常。这意味着,你可能会得到一个NullPointerException,但你会把它当作一个arithmeexception,可能会做错误的事情。在最好的情况下,你仍然错过了一个NullPointerException。这样的事情会使调试变得更加困难,所以不要这样做。
TLDR
找出异常的原因并修复它,这样它就根本不会抛出异常。
如果1。是不可能的,捕获特定的异常并处理它。
永远不要只添加一个try/catch,然后忽略异常!不要那样做!
永远不要使用catch (Exception e),总是捕获特定的异常。这样你就不用再头疼了。