--------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流! --------------------
1.异常概述
异常:异常就是程序在运行时出现的不正常的情况。
异常问题分为:严重问题和非严重问题。
Throwable
|-----Error:表示严重问题
对于此问题一般不会对此异常进行代码的处理
|-----Exception:表示非严重问题
对于此问题会进行对此异常进行代码的处理。
2. 异常的处理
2-1. 在本方法中处理
1.处理方式:
try{}catch(异常对象 变量)finally{}
try{}catch(异常对象 变量)
try{} finally{}
2.处理规则:
在try{检测的代码}catch(捕获的异常)finally{一定会执行的代码(在虚拟机没有停止的前提下)}例如如果在finally{}前面有System.exit(0)的话,那么虚拟机就会停止,后面的代码自然不会执行。
在catch(异常类 变量)捕获异常的时,会按照顺序进行捕获,然后进行处理,所以在写catch()的时候,一定要把子类或者方法抛出的异常写到前面,异常的父类写在后面,例如:一定要把Exception写到最后面catch(Exceptione)
public class ExceptionDemo {
public static void main(String[] args) {
try {
div(4, 0);
} catch (ArithmeticException e) {// 除零异常
e.printStackTrace();
} catch (Exception e) {// 防止有其他的异常没有处理,但是如果把此位置的放到捕获异常的最前面,
e.printStackTrace(); // 那么后面的捕获异常就会没有自导作用,
// 因为此是父类,是按照顺序执行
}
}
public static void div(int a, int b) {
System.out.println(a / b);
}
}
3.异常的信息的输出方式
System.out.println("被零除了!");//自定义的信息 System.out.println(e.getMessage());//异常信息: / by zero System.out.println(e.toString());//异常包.类名 :异常信息 java.lang.ArithmeticException: / by zero e.printStackTrace();//异常包.类名:异常信息 异常位置 /* java.lang.ArithmeticException: / by zero at www.fuxi.yichang.ExceptionDemo.div(ExceptionDemo.java:18) at www.fuxi.yichang.ExceptionDemo.main(ExceptionDemo.java:6) */ e.getMessage()-----》e.toString()----》e.printStackTrace()他们的输出的信息是越来越详细的,但是在开发中,我们是不这样处理的,因为用户是看不懂异常信息并且处理不了的,所以我们是把错误信息写入到一个文件中,然后供管理员查看,来处理异常,这样就可以优化系统程序。 |
2-2.抛出
1.如何抛出
使用throws关键字来抛出异常,在方法中对处理课程出现的异常,在方法的声明上进行抛出,这样在调用此方法的时候,必须在调用此方法的方法中进行处理此异常或者继续抛出,那么这样就可以防止用处在不知情的情况下输入的不正确的信息,就会进行必须的处理,防止程序的结束。
2.抛出声明的规则:
声明异常时,声明的异常要更为详细,这样处理的时候就为具体
对方声明了几个异常,那么我们就处理几个异常,或者抛出几个异常。
public class ExceptionThrow {
public static void main(String[] args) {
try {
div(4, 0);// 除数方法
} catch (ArithmeticException e) {// 除零异常
System.out.println("被零除了!"); // 自定义的信息
} catch (Exception e) {
e.printStackTrace();
}
}
public static void div(int a, int b) throws ArithmeticException {
System.out.println(a / b);
}
}
3. 自定义异常。
3-1.自定义异常的规则
1.自定义异常的了类必继承Exception类。然后你可以重新其中的方法或者直接调用就看你的意向了。
2.继承Exception类的原因,因为你的在Throwable类体系中的类或者是对象需要被抛出,但是只有此Throwable体系中的对象才能被抛出,所以要继承Throwable类或者是子类。可以是Error或者是Exception。
3.自定义的异常要不在本方法中处理了,要不就抛出。(不是继承的RuntimeException类)
4.我们可以定义自己需要的异常,没有给提供的异常,系统中的提供的不够我们使用的,可以按照自己的来自己定义,
3-2.代码举例。
/*自定义的异常*/
class MyDivFuShuException extends Exception {
public MyDivFuShuException(String message) {
super(message);
}
}
public class ZidingyiException {
public static void main(String[] args) {
try {
div(1, -1);
} catch (MyDivFuShuException e) {// 这里捕获的是方法中抛出的异常
System.out.println(e.getMessage());
}
div1(1, -1);
}
/* 自定义的异常把异常抛出 */
public static void div(int a, int b) throws MyDivFuShuException {
if (b < 0)
throw new MyDivFuShuException("自定义的异常,除数不能为零");
System.out.println(a / b);
}
/* 自定义的异常在本方法中就把异常抛出 */
public static void div1(int a, int b) {
try {
if (b < 0)
throw new MyDivFuShuException("自定义的异常,除数不能为零");
System.out.println(a / b);
} catch (MyDivFuShuException e) {
System.out.println(e.getMessage());
}
}
}
3-3.throw和throws的区别
Throws是定义在了函数上,后面可以跟多个异常类,用逗号隔开。
Throw是定义在函数内,后面跟的是异常对象,只能跟一个对象。
4. RuntimeException
4-1.异常分类。
可以分为编译时可以被检测的异常
表示的是Exception类或者是子类,或者是自定义的异常继承的此类,对于此异常的类必须进行try{}处理,或者抛出,并且要进行捕获,要不编译会出现错误,可以参考上面将的Exception
编译时不被检测的异常(运行时异常,RuntimeException以及子类)
4-2.运行时异常的特点
1.在方法体中抛出了运行是异常或者是其子类的话,那么在方法上不用声明抛出的次异常,就是不需要用throws在方法上声明
2.在方法上声明了抛出的运行时异常或者是其子类,那么不需要在调用处,不用进行捕获和处理。
3.在运行时出现了运行是异常,那么必须停止了程序,然后有调用者进行在出错的程序上进行更改和调试。
4.如果要求自定义的异常需要停止程序来运行,那么就让自定义的异常继承RuntimeException类。
public class RuntimeExceptionDemo {
public static void main(String[] args) {
/* ArithmeticException类是RuntimeException的子类 */
Div(2,0);
DivThrow(2,0);
}
/**
* 在此方法中抛出的是RunntimeException子类,此时不需要在方法上声明抛出的此异常
* 编译是不会出错,因为RunntimeException是运行时异常,
*/
public static void Div(int a, int b) {
if (b == 0) {
throw new ArithmeticException("除数不能为零");
}
System.out.println(a / b);
}
/**
* 在此方法中上声明的是是RunntimeException子类,
* 此时在调用处是不需要声明捕获此异常,也可以编译通过
* 因为RunntimeException是运行时异常
*/
public static void DivThrow(int a, int b) throws ArithmeticException {
if (b == 0) {
throw new ArithmeticException("除数不能为零");
}
System.out.println(a / b);
}
}
5. 异常注意点和技巧
当遇到了异常,如果最终有办法出来的话,那么就把捕获到的异常,进行处理的时候,抛给可处理的异常类(catch(xxException e)(throw newkechuliException()))然后这样就可以进行处理了。
在throw new 异常对象,后面不要写任何代码,因为只要throw抛出了异常,后面就能写代码了。{ throw new 异常对象; 在此代码块的范围内,在后面不能写任何代码了}
6. finally的使用
finally{一定会执行的代码}:
一般都是可肯定会执行的代码
大多数都是要执行的就是资源的关闭。一般都是关闭数据库的连接
即使前面有return,finally{}中的代码也一样会执行。
在finally前面有System.exit(0)的话,那么后面的finally{}不会执行,因为虚拟机都停止了。
public class finallyDemo {
public static void main(String[] args) {
try {
int a = 5 / 1;
System.out.println("hello" + a);// 不会执行,因为上面已经出现了异常
} catch (Exception e) {
// e.printStackTrace();
return;
} finally {
System.out.println("finally");// 会执行
}
System.out.println("over");// 会执行,因为前面更已经把异常处理,所以会执行语句
}
}
7. 异常处理的格式
try{}catch(异常对象)finally{}
try{}catch(异常对象) f
try{} finally{}
catch()是用来匹配异常并且处理的的,如果没有被catch处理,那么必须抛出此异常。声明此异常
8.异常的覆盖
1.子类在覆盖父类的时,如果父类的方法抛出了异常,那么子类的覆盖方法只能抛出父类抛出的异常或者其子类。
原因:就是父类在抛出了异常的后,抛给了父类,父类处理的只有自己抛出的异常,所以如果子类抛出了父类没有抛出的异常,那么就不能被处理,所以就会出错误。
2.如果父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类异常的子集。
3.如果父类或者接口的方法没有异常抛出,子类在覆盖方法时,也不可以抛出异常,如果子类方法发生了异常,那么必须进行try{}catch()处理。但是如果是实现的是接口或者抽象类,或者是子类中没有调用父类的构造方法,子类构造方法可以抛出异常并且声明,因为调用的不是同一个方法。
9. 异常练习
求图形的面积。首先把面积方法抽取出来,然后子啊各个图形对象下进行重写,因为各个图形中有各自不同的属性。
class NoValueException extends RuntimeException{
public NoValueException(String message){
super(message);
}
}
interface shape{
void getArea();
}
class Rec implements shape{
private int len;
private int wid;
public Rec(int len,int wid){
if(len<=0 || wid<=0)
throw new NoValueException("数据错误");
this.wid=wid;
this.len=len;
}
public void getArea() {
System.out.println(len*wid);
}
}
public class ShampDemp{
public static void main(String[] args) {
Rec r=new Rec(1,0);
r.getArea();
System.out.println("over");
}
}
10. 异常执行结构图
11. 一个疑问—请解答
/*自定义的异常*/
class MyDivFuShuException extends Exception {
public MyDivFuShuException(String message) {
super(message);
}
}
public class ZidingyiException {
public static void main(String[] args) {
try {
div(1, -1);
} catch (MyDivFuShuException e) {// 这里捕获的是方法中抛出的异常
System.out.println(e.getMessage());
}
try {
div1(1, -1);
// } //catch(MyDivFuShuException e) {//
// 这里捕获自定一的异常,但是方法中没有抛出才异常,不是即使不会出现的异常的,也可以在这里进行捕获呢啊,那为什么还会出错呢
//System.out.println(e.getMessage());
} catch (ArithmeticException e) {// 这里编译不会出错误,这是现有的异常类,捕获不出错误,但是为什么自定义的异常就会出错误呢
System.out.println(e.getMessage());
}
}
/* 自定义的异常把异常抛出 */
public static void div(int a, int b) throws MyDivFuShuException {
if (b < 0)
throw new MyDivFuShuException("自定义的异常,除数不能为零");
System.out.println(a / b);
}
/* 自定义的异常在本方法中就把异常抛出 */
public static void div1(int a, int b) {
try {
if (b < 0)
throw new MyDivFuShuException("自定义的异常,除数不能为零");
System.out.println(a / b);
} catch (MyDivFuShuException e) {
System.out.println(e.getMessage());
}
}
}
解答:点击这里
-------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! --------------------