-------android培训、java培训、期待与您交流! ----------
一 异常概述:
异常就是在程序的运行过程中所发生的不正常的事件,例如:所需文件找不到.、网络连接不通或中断、算术运算出错(如被零除)、数组下标越界、装载了
一个不 存在的类,对null对象操作,类型转换异常等等!都是所谓的异常因此导致程序的运行中断或不出错;在我们的现实生活中就有很多的实例:例如
早上去上班时因为堵车,上班迟到了;或是在外面逛街的时候突然下起了大雨而有没有带伞等等.........这都是我们在现实生活中经常会遇到的异常;但是在现
实生活 中遇到异常我们会有处理异常的机制;那么我们程序中遇到的异常我们有会怎么去处理呢,这时我们就会有处理程序异常的机制;
二 异常的分类:
Throwable类;所有异常类型都是Throwable类的子类:它派生了两个子类:Error类和Exception类;
(一):一种是严重的问题(Error):对于(Error)这种异常一般不做针对性的处理;
Error 是 Throwable
的子类,用于指示合理的应用程序不应该试图捕获的严重问题;比如内存溢出动态链接失败,虚拟机出错误,而这种问题应用程序
不应该 抛出(一般有虚拟机抛出);假如出现了这种问题除了尽力使程序安全退出外,在其他方面都是无能为力的,所以在进行程序设计时应该更加关注
Exception类;
(二):另一种是非严重的问题(Exception):对于(Exception)这种异常将做针对性的处理;
Exception
类及其子类是 Throwable
的一种形式,它指出了合理的应用程序想要捕获的条件;比如所需的文件找不到,网咯中断,算术运算出错
(如被0除了数组越界等等......它的各种不同的子类分别对应不同类型的异常。
(三)运行时异常:包括RuntimeException及其所有子类,不要求程序必须对他们做出处理,例如在下面的示例中的多个catch处理异常中捕捉
(InputMismatchException)和(ArithmeticException)异常在编译时不会发生异常但在运行时如果出现了相应的异常将会被捕捉到;
(四)Checked异常:(非运行时异常):除了运行时异常外的其他有Exception继承来的异常类。程序必须捕获或者声明抛出这种异常,否则会出现编译异常,
无法 通过编译。这种异常的处理方式包括两种:(1)通过try --catch在当前位置捕获并处理异常,还可以通过throws声明抛出异常交给上一级调用方处理;
三 异常的处理:
异常处理机制就像我们对现实生活中出现的意外情况一样,但在我们的程序出现异常时我们有怎么去处理呢:这时我们就可以通过java提供给我们的五个关键
字来解决程序出现的异常提前做好我们能预先想到的异常做出相应的异常处理;因此java处理异常通过的五个关键字: try 、catch 、finally 、thorw 、thorws ;
如下详解
(一) try 、catch 的使用如示例;
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Scanner in=new Scanner(System.in);
System.out.print("请输入一个被除数:");
int num1=in.nextInt();
System.out.print("请输入一个被除数:");
int num2=in.nextInt();
System.out.println(String.format("%d / %d=%d", num1,num2,num1/num2));
System.out.println("谢谢使用!");
} catch (Exception e) {
System.out.println("请输入整数!");
e.printStackTrace();
}
/*
* 当我们输入的数不为整数是将会出现异常:报出如下错误异常:ArithmeticException ;但是我们不做了这样的处理(try{}catch{} )
* 我们的程序将会非正常的退出;所以我们在预知的情况下使用(try{}catch{} ) 做出相应的处理!
*
* 请输入一个被除数:4
* 请输入一个被除数:0
* java.lang.ArithmeticException: / by zero java.lang.ArithmeticException: / by zero
* java.lang.ArithmeticException: / by zero
*/
}
try:如果try块中的代码都正常的执行完毕,不会发生异常那么catch块中的所有语句都将会被忽略;但是在try中的代码块中出现了异常,并且这个异常与
catch中声明了异常类型相匹配,那么try中的其余代码将被忽略不在执行,这时系统将自动生成相应的异常对象,包括异常的类型、异常出现时程
序的运状态以及该异常的详细描述。如果这个异常对象与相应的catch中声明的异常类型相匹配会把该异常对象赋给catch后面的异常参数,这时
就执行catch中相应的异常处理;
(二)多个catch处理异常:
在try中的一段代码块中可能发生多种异常,这时我们就应该使用多重catch来处理不同的异常了;;但是排列的顺序是从子类到父类,最后一个一般都
是Exception类。因为按照匹配的原则如果把父类异常放到前面,后面的catch将不会执行到;
在执行时系统是从上到下的分别对每个catch语句块处理的异常类进行检测,在找到匹配的catch时后面的catch将不在执行;
如下示例是对多重catch的使用:
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Scanner in=new Scanner(System.in);
System.out.print("请输入一个被除数:");
int num1=in.nextInt();
System.out.print("请输入一个被除数:");
int num2=in.nextInt();
System.out.println(String.format("%d / %d=%d", num1,num2,num1/num2));
System.out.println("谢谢使用!");
} catch (InputMismatchException e) {
System.out.println("除数和被除数必须为整数!");
}catch(ArithmeticException e){
System.out.println("除数不能为零!");
}catch(Exception e){
System.out.println("未知异常!");
}
}
注意:
(1)Exception在开发中一般不写;为什么呢,原因是在程序中一定要定义具体的处理方式;就算发生了异常也能知道发生了什么异常在什么位置发生
的这样在测试的时候就能解决问题,要是写了Exception发生了异常但是给catch处理了就不知道错在哪了就很难找到其原因了;
(2)对方声明了几个异常,就对应的有几个catch块,不要定义多余的catch块;
(三)try 、catch、finally的使用:
(1) finally块的语句是无论是否发生异常都执行的语句,但只有一种情况不执行就是System.exit(1);finally一般用于关闭链接释放资源。
(2) try 、catch、finally结构中try块是必须的,catch 和finally是可选的,但两者至少出现其中一个也可以全部出现;
(3) 注意:
即使在try块和catch块中存在return语句,finally块中的语句也是会执行,发生异常时的执行顺序是:执行try块或catch中的return之前的语句,
执行finally 中的语句,执行try块或catch中的return语句退出。
finally块语句唯一不执行的情况是:在异常处理代码中执行System.exit(1),将退出java虚拟机。
如示例:这是一个说明return是在finally执行后才返回的,且在finally无法改变返回值的示例。
public static void main(String[] args) {
// TODO Auto-generated method stub
//调用静态方法
String name=show();
//打印测试结果
System.out.println(name+"--返回后的语句!");
}
//创建一个返回字符串的静态方法;
public static String show(){
//要返回的字符串
String name="return";
try {
//返回语句;
return name;
}finally{
//查看执行return语句后会不会改变其name的值;
name="finally";
System.out.println("finally语句以执行,且无法改变name的值!");
}
}
(四)自定义异常:为什么要定义自定异常呢?与throw和throws的使用:
(1) 因为在日常的开发项目中会出现特有的问题,而这些问题并未被java所描述并封装对象;所以对于这些特殊的问题可以按照java对问题封装的思想
将特有的问题进行自定义的异常封装;
(2):如何自定义异常信息呢?
因为父类中已经不异常信息的操作已经做完了,所以子类只要在构造是,将异常信息传给父类通过super语句这样就可以直接通过getMessage方法
获取自定义的信息了;
(3)自定义异常类必须继承Exception;因为:异常体系有一个特点:因为异常类和异常类的对象都被抛出;他们都具备可抛性,而这个可抛性是
Throwable这个体系中独有的特点;
只有这个体系中的类和对象才可以被throw和throws操作;
throws和throw的区别:
throws是使用在函数上:throws后面跟的异常类,可以跟多个,用逗号隔开;
throw是使用在函数内:throw后面跟的是异常对象:当函数内容有throw抛出异常对象,并为进行try处理时,必须要在函数上声明,否则编译失败。
注意:RunTimeException除外,也就是说,函数内如果抛出的是RunTimeException异常,在函数上可以不声明;
如示例:自定异常
public static void main(String[] args) {
// TODO Auto-generated method stub
//使用try 、catch捕捉异常
try {
int d=new Tests().show(5, 0);
} catch (Abnormal e) {
//调用getMessage()方法输出自定异常信息;
System.out.println(e.getMessage());
}
}
}
//自定义异常类继承Exception
class Abnormal extends Exception{
//重载父类的构造函数
public Abnormal(String name){
super(name);
}
}
class Tests{
//使用throws在函数上抛出异常类
public int show(int a,int b) throws Abnormal{
//逻辑判断如果除数小于
if(b<=0){
//使用throw在函数内抛出异常类对象
throw new Abnormal("除数不能是0;");
}
return a/b;
}
注意:如果自定义异常的发生,无法再继续运行就让自定义异常继承RuntimeException;
(五):异常在子父类覆盖中的体现:
(1):子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或该异常的子类;
(2)如果父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类异常的子集:就是说子类抛出的异常不能超过父类,要父类异常的范围内;
(3)如果父类或接口的方法中没有异常抛出那么子类在覆盖方法时也不可以抛出异常;如果子类方法发生了异常,一定要进行try处理绝对不能抛出;
-------android培训、java培训、期待与您交流! ----------