您的位置:首页 > 编程语言 > Java开发

JAVA异常处理机制(基础知识)

2015-05-24 12:01 573 查看

JAVA异常处理机制

一、异常概述

       世界上最真情的相依,是你在try我在catch,无论你发神马脾气,我都默默接受,静静处理。

       现在让我们来谈谈JAVA中的异常,嘻嘻。。。

       为了应对运行期间可能出现的错误,提高程序的的稳健性,Java中定义了强大的异常处理机制。Java的异常机制在增强程序稳健性的同时(围绕异常声明,在编译期间就具有严格的异常制度),增强了业务代码的逻辑性和连贯性(通过try-catch,避免了C等语言下的业务逻辑代码和异常检测代码严重混合)。在编程中,如果程序出现了问题,我们没有做任何处理,最终jvm会做出默认的处理。把异常的名称,原因及出现的问题等信息输出在控制台,同时会结束程序。如果我们用try..catch处理,在try里面发现问题后,jvm会帮我们生成一个异常对象,然后把这个对象抛出,和catch里面的类进行匹配。如果该对象是某个类型的,就会执行该catch里面的处理信息。

1、异常分类

请看下面这个情景

今天天气很好,张三出去旅游。骑着自行车,去山里面呼吸新鲜空气。但是张三现在遇到下面三个问题。
问题1:山路塌陷了,张三及时停住了,但是过不去了。严重的问题。
问题2:张三出门推自行车,发现气没了,把气吹起来。出发前就应该检查的问题。

        问题3:张三骑着车在山路上惬意的行驶着,山路两边是有小石子的,中间是平坦的水泥路。一直在平坦的水泥路上行驶是没有任何问题的,但是呢,他偏偏喜欢 骑到小石子上,结果爆                        胎了。旅游的过程中出现的问题。no zuo no die。

程序的异常:Throwable
严重问题:Error 我们不处理。这种问题一般都是很严重的,比如说内存溢出。
一般问题:Exception
编译期问题:不是RuntimeException的异常 必须进行处理的,因为你不处理,编译就不能通过。

运行期问题:RuntimeException这种问题我们也不处理,因为是你的问题,而且这个问题出现肯定是我们的代码不够严谨,需要修正代码的。

对应上面的情景:
Error:走到半路上,发生山路塌陷,或者出现了泥石流,这个问题很严重,不是张三能够立马解决的。
Exception:出门前,张三要看看车轮子以及车链子等是否还在
RuntimeException:在骑车的过程中,有好路不走,偏偏要走石子路
让我们通过下面的图具体看看JAVA中的异常
   异常体系结构图:



二、异常处理机制

1、异常的处理一:

A:JVM的默认处理
把异常的名称,原因,位置等信息输出在控制台,但是呢程序不能继续执行了。
B:自己处理
a:try...catch...finally
自己编写处理代码,后面的程序可以继续执行
b:throws
把自己处理不了的,在方法上声明,告诉调用者,这里有问题
示例代码:

public class ExceptionDemo {
public static void main(String[] args) {
int a = 10;
int b = 0;
int[] arr = { 1, 2, 3 };
// 爷爷在最后
try {
System.out.println(a / b);
System.out.println(arr[3]);
System.out.println("这里出现了一个异常,你不太清楚是谁,该怎么办呢?");
} catch (ArithmeticException e) {
System.out.println("除数不能为0");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("你访问了不该的访问的索引");
} catch (Exception e) {
System.out.println("出问题了");
}
}
}
看着上面的代码,对于多个异常的处理,我们或许觉得catch块过多,这样显得很臃肿,不利于程序的可读性,所以JDK7提供了一种新的解决方法,如下:

示例代码:

public class ExceptionDemo {
public static void main(String[] args) {
int a = 10;
int b = 0;
int[] arr = { 1, 2, 3 };
try {
System.out.println(a / b);
System.out.println(arr[3]);
} catch (ArithmeticException |ArrayIndexOutOfBoundsException e) {
System.out.println("程序出问题了。。。");
}
}
}
以这种方式,代码是不是变的清晰了很多呢,嘻嘻。。。
注意:这种方式虽然简洁,但是也不够好。主要体现在如下两点。
第一,处理方式是一致的,其实在实际开发中,还是有些场合符合这个用法的,比如对数据库操作,我管你是插入失败,还是删除失败,总之我给你个信息---你操作失败。
第二,catch后面的异常必须是同级关系。

2、异常处理方式二

 有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。或者说,我处理不了,我就不处理了。为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出。
格式:
throws 异常类名
注意:这个格式必须跟在方法的括号后面。尽量不要在main方法上抛出异常。
    定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在方法上标识。

3、异常中要了解的几个方法

public String getMessage():异常的消息字符串
public String toString():返回异常的简单信息描述
 此对象的类的 name(全路径名),": "(冒号和一个空格) 
调用此对象 getLocalizedMessage()方法的结果 (默认返回的是getMessage()的内容)
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。把信息输出在控制台。

三、自定义异常

java不可能对所有的情况都考虑到,所以,在实际的开发中,我们可能需要自己定义异常。而我们自己随意的写一个类,是不能作为异常类来看的,要想你的类
是一个异常类,就必须继承自Exception或者RuntimeException。继承自Exception是编译时的异常,继承RuntimeException是运行时期的异常。
示例代码:

public class MyException extends Exception {
public MyException() {
}

public MyException(String message) {
super(message);
}
}
/*
* 自定义异常测试类
*/
public class StudentDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生成绩:");
int score = sc.nextInt();

Teacher t = new Teacher();
try {
t.check(score);
} catch (MyException e) {
e.printStackTrace();
}
}
}

public class Teacher {
//如果你自定义的异常时继承自RuntimeException,是不需要throws MyException的
public void check(int score) throws MyException {
if (score > 100 || score < 0) {
throw new MyException("分数必须在0-100之间");
} else {
System.out.println("分数没有问题");
}
}
}


四、面试题举例

1、final, finally, finalize的区别。

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。

内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……

finally是异常处理语句结构的一部分,表示总是执行。

finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

JVM不保证此方法总被调用。

2、error和exception有什么区别?

error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 exception表示一种设计或实现问题。

也就是说,它表示如果程序运行正常,从不会发生的情况。

3、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?

throws捕获并向外抛出异常

throw抛出异常

try catch是内部捕获异常并做自定义处理

finally是无论是否有异常都会被处理的语句,除非在finally前存在被执行的System.exit(int i)时除外

4、throws和throw的区别?

throws用在方法声明后面,跟的是异常类名,可以跟多个异常类名,用逗号隔开,表示抛出异常,由该方法的调用者来处理,throws表示出现异常的一种可能性,并不一定会发生这些异常

throw用在方法体内,跟的是异常对象名,只能抛出一个异常对象名,表示抛出异常,由方法体内的语句处理,throw则是抛出了异常,执行throw则一定抛出了某种异常

5、如果catch里面有return语句,请问finally里面的代码还会执行吗?

 如果会,请问是在return前,还是return后。

 会。前。

 准确的说,应该是在中间。

看下面的程序:

public class FinallyDemo {
public static void main(String[] args) {
System.out.println(getInt());
}

public static int getInt() {
int a = 10;
try {
System.out.println(a / 0);
a = 20;
} catch (ArithmeticException e) {
a = 30;
return a;
/*
* return a在程序执行到这一步的时候,这里不是return a而是return 30;这个返回路径就形成了。
* 但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40
* 再次回到以前的返回路径,继续走return 30;
*/
} finally {
a = 40;
//return a;//如果这样结果就是40了。
}
return a;
}
}
运行结果是30、理由如上
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: