异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件)。Java异常处理 是代替日渐衰落的error code方法的新法,提供error code 所未能具体的优势。异常处理分离了接收和处理错误代码。这个功能理清了编程者的思绪,也帮助代码增强了可读性,方便了维护者的阅读和理解。 异常处理(又称为错误处理)功能提供了处理程序运行时出现的任何意外或异常情况的方法。异常处理使用 try、catch 和 finally 关键字来尝试可能未成功的操作,处理失败,以及在事后清理资源。
try{
///可能会抛出异常的代码
}catch(Type1 id1){
//处理Type1类型异常的代码
}catch(Type2 id2){
//处理Type2类型异常的代码
}
try块中放置可能会发生异常的代码(但是我们不知道具体会发生哪种异常)。如果异常发生了,try块抛出系统自动生成的异常对象,然后异常处理机制将负责搜寻参数与异常类型相匹配的第一个处理程序,然后进行catch语句执行(不会在向下查找)。如果我们的catch语句没有匹配到,那么JVM虚拟机还是会抛出异常的。
如果在当前方法不知道该如何处理该异常时,则可以使用throws对异常进行抛出给调用者处理或者交给JVM。JVM对异常的处理方式是:打印异常的跟踪栈信息并终止程序运行。 throws在使用时应处于方法签名之后使用,可以抛出多种异常并用英文字符逗号’,’隔开。下面是一个例子:
public void f() throws ClassNotFoundException,IOException{}
这样我们调用f()方法的时候必须要catch-ClassNotFoundException和IOException这两个异常或者catch-Exception基类。
注意:
throws的这种使用方式只是Java编译期要求我们这样做的,我们完全可以只在方法声明中throws相关异常,但是在方法里面却不抛出任何异常,这样也能通过编译,我们通过这种方式间接的绕过了Java编译期的检查。这种方式有一个好处:为异常先占一个位置,以后就可以抛出这种异常而不需要修改已有的代码。在定义抽象类和接口的时候这种设计很重要,这样派生类或者接口实现就可以抛出这些预先声明的异常。
异常类的基类Exception中提供了一组方法用来获取异常的一些信息.所以如果我们获得了一个异常对象,那么我们就可以打印出一些有用的信息,最常用的就是void printStackTrace()这个方法,这个方法将返回一个由栈轨迹中的元素所构成的数组,其中每个元素都表示栈中的一帧.元素0是栈顶元素,并且是调用序列中的最后一个方法调用(这个异常被创建和抛出之处);他有几个不同的重载版本,可以将信息输出到不同的流中去.下面的代码显示了如何打印基本的异常信息:
public void f() throws IOException{
System.out.println("Throws SimpleException from f()");
throw new IOException("Crash");
}
public static void main(String[] agrs) {
try {
new B().f();
} catch (IOException e) {
System.out.println("Caught Exception");
System.out.println("getMessage(): "+e.getMessage());
System.out.println("getLocalizedMessage(): "+e.getLocalizedMessage());
System.out.println("toString(): "+e.toString());
System.out.println("printStackTrace(): ");
e.printStackTrace(System.out);
}
}
我们来看输出:
Throws SimpleException from f()
Caught Exception
getMessage(): Crash
getLocalizedMessage(): Crash
toString(): java.io.IOException: Crash
printStackTrace():
java.io.IOException: Crash
at com.learn.example.B.f(RunMain.java:19)
at com.learn.example.RunMain.main(RunMain.java:26)
引入finally语句的原因是我们希望一些代码总是能得到执行,无论try块中是否抛出异常.这样异常处理的基本格式变成了下面这样:
try{
//可能会抛出异常的代码
}
catch(Type1 id1){
//处理Type1类型异常的代码
}
catch(Type2 id2){
//处理Type2类型异常的代码
}
finally{
//总是会执行的代码
}
在Java中希望除内存以外的资源恢复到它们的初始状态的时候需要使用的finally语句。例如打开的文件或者网络连接,屏幕上的绘制的图像等。下面我们来看一下案例:
public class FinallyException {
static int count = 0;
public static void main(String[] args) {
while (true){
try {
if (count++ == 0){
throw new ThreeException();
}
System.out.println("no Exception");
}catch (ThreeException e){
System.out.println("ThreeException");
}finally {
System.out.println("in finally cause");
if(count == 2)
break;
}
}
}
}
class ThreeException extends Exception{}
我们来看输出:
ThreeException
in finally cause
no Exception
in finally cause
如果我们在try块或者catch块里面有return语句的话,那么finally语句还会执行吗?我们看下面的例子:
public class MultipleReturns {
public static void f(int i){
System.out.println("start.......");
try {
System.out.println("1");
if(i == 1)
return;
System.out.println("2");
if (i == 2)
return;
System.out.println("3");
if(i == 3)
return;
System.out.println("else");
return;
}finally {
System.out.println("end");
}
}
public static void main(String[] args) {
for (int i = 1; i<4; i++){
f(i);
}
}
}
我们来看运行结果:
start.......
1
end
start.......
1
2
end
start.......
1
2
3
end
我们看到即使我们在try或者catch块中使用了return语句,finally子句还是会执行。那么有什么情况finally子句不会执行呢?
有下面两种情况会导致Java异常的丢失
1)finally中重写抛出异常(finally中重写抛出另一种异常会覆盖原来捕捉到的异常)
2)在finally子句中返回(即return)
以上就是Java异常处理的相关知识,Java中的异常处理远远不是一篇文章能够讲清楚的,其中涉及到了很多的知识点和专业术语,我们可以到动力节点在线的视频课程里学习Java异常处理的各种知识,充实自己。
提枪策马乘胜追击04-21 20:01
代码小兵92504-17 16:07
代码小兵98804-25 13:57
杨晶珍05-11 14:54