黑马程序员——异常
2015-06-11 11:44
525 查看
——- android培训、java培训、期待与您交流! ———-
异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。
其实就是java对不正常情况进行描述后的对象体现
对于问题的划分:两种:一种是严重的问题,一种是非严重的问题。
对于严重的:java通过Error类进行描述。
对于Error一般不编写针对性的代码对其进行处理。
对于非严重的:java通过Exception类进行描述。
对于Exception可以使用针对性的处理方式进行处理。
无论Error或者Exception都具有一些共性内容。
比如:不正常情况的信息,引发原因等。
+++++|—Error
+++++|—Exception
+++++++++++|—RuntimeException
try{
需要被检测的代码;
}
catch(异常类 变量){
处理异常代码:(处理方式)
}
finally{
一定会执行的语句;
}
代码示例:
那么就在函数上通过throws声明该功能可能会出现问题,
这样做的好处是,让使用这个函数的方法必须try
如:
代码示例:
2.对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
如果将父类异常放在最上面,那么会导致下面的异常永远不会执行得到,
那么,下面的异常就相当于废话一样
3.如果有多个catch块,出现异常时只能执行一个catch块,因为一旦发现异常
那么该程序就会直接跳到对应的catch块中执行,所以catch块只能执行一个。
建议:进行catch处理时,catch中一定要定义处理方式。
不要简单定义一句e.printStackTrace(),
也不要简单的就书写一条输出语句,因为这样客户在使用该软件发生异常的时候,
客户不知道这是什么东西,一个简单的输出语句不能解决客户的问题
代码示例:
要么在内部try catch处理。
要么在函数上声明,让调用者处理。
一般情况下,函数内抛出异常,函数上需要声明。
继承它们的原因:
异常体系有一个特点:因为异常类和异常对象都被抛出。
他们都具备可抛性,这个可抛性是Exception、Error或Throwable
体系中的独有特点。
只有这个体系中的类和对象才可以被throws和throw操作。
如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了。
所以子类只要在构造时,将异常信息通过super语句传给父类
那么就可以直接通过getMessage或toString方法获取自定义的异常信息。
代码示例:
throw定义在函数内。
throws后面跟异常类。可以跟多个,用逗号隔开。
throw后面跟异常对象。
Exception中有一个特殊的子类异常RunTimeException 运行时异常。
如果函数内容抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了该异常。调用者可以不用进行处理,编译一样通过。
之所以不用函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止后,
对代码进行修正。
如:
自定义异常时:如果该异常的发生,无法再继续进行运算,
就让自定义异常继承RunTimeException。
代码示例:
finally使用的例子:
代码示例:
2.如果父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类的异常子集,或者该异常的子类,或者进行try处理。
3.如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
如果子类方法发生了异常。就必须要进行try处理,绝对不能抛出。
代码示例:
异常体系:
Throwable
++++|—–Errow
++++|—–Excepting
+++++++|—–RunTimeException
异常体系的特点:异常体系中的所有类以及建立的对象都具备可抛性。
也就是说可以被throw和throws关键字所操作。
只有异常体系具备这个特点。
throw和throws的用法:
throw定义在函数内,用于抛出异常对象。
throws定义在函数上,用于抛出异常类,可以抛出多个,用逗号隔开。
当函数内容有throw抛出异常对象,并未进行try处理。必须要在函数上声明,否则编译失败。
注意:RunTimeException除外。也就说,函数内如果抛出RunTimeException异常或者RunTimeException
异常的子类,函数上可以不用声明。
如果函数声明了异常,调用者需要进行处理。处理方式可以throws,可以try。
异常有两种:
编译时被检测异常
该异常在编译时,如果没有处理(没有throw也没有try),那么编译失败
该异常被标识,代表着可以被处理。
运行时异常(编译时不检测)
在编译时,不需要处理,编译器不检查。
该异常的发生,建议不处理,让程序停止。需要对代码进行修正。
注意:
1,finally中定义的通常是,关闭资源代码,因为资源必须要释放
2,finally只有一种情况不会执行。当程序执行到System.exit(0)时,fianlly不会执行。
//System.exit(0) –> 系统退出。jvm结束。
自定义异常:
定义类继承Exception或者RunTimeException
1,为了让自定义类具备可抛性。
2,让该类具备操作异常的共性方法。
异常的好处:
1,将问题进行封装。
2,将正常流程代码和问题处理代码相分离,方便与阅读。
异常的处理原则:
1,处理方式有两种:try 或者 throws。
2,调用到抛出异常的功能时,抛出几个,就处理几个(不要多处理或者少处理)
一个try对应多个catch。
3,多个catch中,父类的catch放到最下面。
4,catch内,需要定义针对性的处理方式,不要简单的定义printStackTrace,输出语句。
也不要不写。
在子父类覆盖时:
1,子类抛出的异常必须是父类异常的子类或者子集。
2,如果父类或者接口中没有异常抛出时,子类覆盖出现异常,只能try,不能抛
什么是异常?
就是程序运行时出现不正常情况。异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。
其实就是java对不正常情况进行描述后的对象体现
对于问题的划分:两种:一种是严重的问题,一种是非严重的问题。
对于严重的:java通过Error类进行描述。
对于Error一般不编写针对性的代码对其进行处理。
对于非严重的:java通过Exception类进行描述。
对于Exception可以使用针对性的处理方式进行处理。
无论Error或者Exception都具有一些共性内容。
比如:不正常情况的信息,引发原因等。
异常中的体系结构:
Throwable+++++|—Error
+++++|—Exception
+++++++++++|—RuntimeException
异常的语法:
java特供了特有的语句进行处理。try{
需要被检测的代码;
}
catch(异常类 变量){
处理异常代码:(处理方式)
}
finally{
一定会执行的语句;
}
代码示例:
/* 异常的使用: */ class ExceptionDemo { int div(int a, int b){ return a / b; //此处抛出new ArithmeticException()异常,算数异常 } } public class Demo { public static void main(String[] args) { ExceptionDemo d = new ExceptionDemo(); try{ //此处检测是否有new ArithmeticException()异常,将异常传给catch int x = d.div(5,0); System.out.println(d.div(5, 0)); } //此处捕获异常,相当于Exception e = new ArithmeticException(); catch(Exception e){ System.out.println("被除数不能为零"); //System.out.println(e.getMessage()); // /by zero //System.out.println(e.toString());//异常名称:异常信息 //e.printStackTrace();// 异常名称,异常信息,出现异常的位置。 //jvm默认的异常处理机制,就是在调用printStackTrace()方法 //打印异常的堆栈的跟踪信息 } System.out.println("over"); /* 结果: 被除数不能为零 over */ } }
throws关键字:
在编写程序时,如果某个函数在功能上可能会出现问题,那么就在函数上通过throws声明该功能可能会出现问题,
这样做的好处是,让使用这个函数的方法必须try
如:
int div(int a, int b) throws Exception{//在功能上通过throws的关键字声明了该功能可能会出现问题 return a / b; // 因为a/b,如果b的值为0,那么会出问题,所以得在函数上声明此函数可能出问题 }
代码示例:
/* 在函数上声明异常。 便于提高安全性,让调用者进行处理,不处理则编译失败 */ class ExceptionDemo { int div(int a, int b) throws Exception{//在函数上通过throws的关键字声明了该功能有可能会出现异常 return a / b; } } public class Demo { public static void main(String[] args) //throws Exception { ExceptionDemo d = new ExceptionDemo(); try {//因为已经知道了div()功能有可以会出现异常,那么此处必须处理异常, //否则该方法必须也用throws声明可能会出现异常 System.out.println(d.div(5, 4)); } catch (Exception e) { System.out.println("被除数不能为零"); } System.out.println("over"); /* 结果: 1 over */ } } //简而言之:用throws关键字声明方法可能会出现异常,那么在使用该方法时, //要么处理异常,要么再用throws关键字声明可能会出现异常
多异常:
1.声明异常时,建议声明更具体的异常。这样处理的可以更具体。2.对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
如果将父类异常放在最上面,那么会导致下面的异常永远不会执行得到,
那么,下面的异常就相当于废话一样
3.如果有多个catch块,出现异常时只能执行一个catch块,因为一旦发现异常
那么该程序就会直接跳到对应的catch块中执行,所以catch块只能执行一个。
建议:进行catch处理时,catch中一定要定义处理方式。
不要简单定义一句e.printStackTrace(),
也不要简单的就书写一条输出语句,因为这样客户在使用该软件发生异常的时候,
客户不知道这是什么东西,一个简单的输出语句不能解决客户的问题
代码示例:
/* 多异常的使用 */ class ExceptionDemo { //在该方法上声明多个异常 int div(int a, int b) throws ArithmeticException, ArrayIndexOutOfBoundsException { int[] x = new int[a]; // 若此处出异常则抛出ArrayIndexOutOfBoundsException-->(数组角标越界异常) System.out.println("x[4]=" + x[4]); // 若此处出异常则抛出ArithmeticException -->(算数异常) return a / b; } } public class Demo { public static void main(String[] args) { ExceptionDemo d = new ExceptionDemo(); try { d.div(5, 0);// 执行此方法导致-->算数异常 // d.div(4, 1);//执行此方法导致-->数组角标越界异常 } catch (ArithmeticException e) { System.out.println("除数不能为零"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("数组角标越界了"); } System.out.println("over"); /* 结果: x[4]=0 除数不能为零 over */ } }
throw关键字:
当在函数内部出现了throw抛出异常对象,那么就必须要给出对应的处理动作。要么在内部try catch处理。
要么在函数上声明,让调用者处理。
一般情况下,函数内抛出异常,函数上需要声明。
自定义异常:
必须是自定义类继承Exception、Error、Throwable继承它们的原因:
异常体系有一个特点:因为异常类和异常对象都被抛出。
他们都具备可抛性,这个可抛性是Exception、Error或Throwable
体系中的独有特点。
只有这个体系中的类和对象才可以被throws和throw操作。
如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了。
所以子类只要在构造时,将异常信息通过super语句传给父类
那么就可以直接通过getMessage或toString方法获取自定义的异常信息。
代码示例:
/* 需求:在本程序中,对于除数是-1,也视为是错误的,是无法进行运算的, 那么就需要对这个问题进行自定义的描述。 */ //创建一个FuShuException类,继承Exception,那么这个类就成为一个自定义异常类 class FuShuException extends Exception{ private int value; public FuShuException(String string,int value){ //子类只要在构造时,将异常信息通过super语句传给父类 //那么就可以直接通过getMessage或toString方法获取自定义的异常信息。 super(string); this.value = value; } public int getValue(){ return value; } } class ExceptionDemo { int div(int a, int b) throws FuShuException { //如果输入的b小于0,则抛出异常, //同时函数上通过throws的关键字声明该功能有可能会出现异常 if(b<0) //手动通过throw关键字抛出一个自定义异常对象 throw new FuShuException("此异常为负数异常",b); return a / b; } } public class Demo { public static void main(String[] args) { ExceptionDemo d = new ExceptionDemo(); try { d.div(5, -9); } catch (FuShuException e) { //通过toString方法获取自定义的异常信息。 System.out.println(e.toString());//结果:此异常为负数异常 //调用自定义异常中错误的值 System.out.println("错误的负数是"+e.getValue());//结果:错误的负数是-9 } System.out.println("over"); } } /* 结果 FuShuException: 此异常为负数异常 错误的负数是-9 over */
throws和throw区别:
throws定义在函数上。throw定义在函数内。
throws后面跟异常类。可以跟多个,用逗号隔开。
throw后面跟异常对象。
特殊的异常RunTimeException
RunTimeException异常Exception中有一个特殊的子类异常RunTimeException 运行时异常。
如果函数内容抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了该异常。调用者可以不用进行处理,编译一样通过。
之所以不用函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止后,
对代码进行修正。
如:
class ExceptionDemo { int div(int a, int b) //throws ArithmeticException//此处声明异常,调用者可以不用进行处理 { if(b == 0) throw new ArithmeticException("除数为0");//此处抛出异常,函数上可以不用声明 return a / b; } }
自定义异常时:如果该异常的发生,无法再继续进行运算,
就让自定义异常继承RunTimeException。
代码示例:
/* RuntimeException异常的演示: */ class FuShuException extends RuntimeException {//继承RuntimeException异常 private int value; public FuShuException(String string, int value) { super(string); this.value = value; } public int getValue() { return value; } } class ExceptionDemo { int div(int a, int b) // throws FuShuException//因为自定义异常继承的是RuntimeException,所以函数可以不用声明异常。因为发成异常时不希望被处理 { if (b < 0) throw new FuShuException("此异常为负数异常", b);//抛出异常 if (b == 0) throw new FuShuException("0不能为除数", 0); return a / b; } } public class Demo { public static void main(String[] args) { ExceptionDemo d = new ExceptionDemo(); // try { d.div(5, 0);//因为函数没有声明异常,所以这里可以不用try处理 // } catch (FuShuException e) { // System.out.println(e.toString()); // System.out.println("错误的负数是"+e.getValue()) // } System.out.println("over"); } } /* 运行结果: Exception in thread "main" FuShuException: 0不能为除数 at ExceptionDemo.div(Demo.java:24) at Demo.main(Demo.java:34) */
finally
finally:定义一定执行的代码。 通常用于关闭资源finally使用的例子:
public void method(){ try{ 连接数据库 //数据操作可能会抛出一个异常 throw new SQLException(); //导致程序无法继续向下运行,最终会导致无法关闭数据库 数据操作 } catch(SQLException e){ 对数据库异常进行处理; throw new NoException();//处理完异常了之后,必定要返回一个结果 } finally{ 关闭数据库 //将关闭数据库放在finally中,不管数据操作是否成功,都肯定会关闭数据库肯定 } }
代码示例:
class FuShuException extends Exception { public FuShuException() { } public FuShuException(String string) { super(string); } } class ExceptionDemo { public int div(int a, int b) throws FuShuException { if (b < 0) throw new FuShuException("除数不能为负数"); return a / b; } } public class Demo { public static void main(String[] args) { ExceptionDemo ed = new ExceptionDemo(); try { ed.div(5, -2); } catch (FuShuException e) { System.out.println(e.toString()); //在此处加了个return语句后,System.out.println("over")就不会执行, //但是finally中的一句还会执行 return; } //finally中的数据肯定会执行 finally { System.out.println("finally"); } System.out.println("over"); /* 结果: FuShuException: 除数不能为负数 finally */ } }
异常的三种使用格式:
第一种格式 try{ } catch{ } 第二种格式 try{ } catch{ } finally{ } 第三种格式 try{ } finally{ } //第三种格式的一般使用方式: //不管程序是否检测到异常,都必须关闭资源 //如: class ExceptionDemo { public void function() throws Exception{ try{ throw new Exception(); }finally{ //关闭资源 } } }
异常在子父类覆盖中的体现:
1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类,或者进行try处理。2.如果父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类的异常子集,或者该异常的子类,或者进行try处理。
3.如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
如果子类方法发生了异常。就必须要进行try处理,绝对不能抛出。
代码示例:
/* * *需求:有一个圆形和长方形。 *都可以获取面积。对于面积如果出现非法的数值,视为是获取面积出现问题。 *问题通过异常表示。 * *思路: *1.因为三角形和长方形都是图形,他们就应该具备求面积的方法, * 所以将求面积的方法定义为抽象的 * *2.定义三角形和长方形类,继承图形类,实现图形类中求面积的方法 * *3.在求面积的时候可能会出现非法值,例如:圆的半径= -2。所以应该自定义 * 一个异常类,判断如果输入的数值不非法,那么直接抛出异常。 * *4.因为数值非法这个异常的不可处理的,所以自定义的异常应该继承RuntimeException */ abstract class TuXing { // 图形类 abstract double getMianJi();// 获取面积方法 } class FuShuException extends RuntimeException {// 自定义异常 public FuShuException() { } public FuShuException(String s) { super(s);//将异常的信息传递给父类 } } class YuanXing extends TuXing {// 圆形类 private double r;//半径 public YuanXing() { this.r = 1.0; } public YuanXing(double r) { if (r <= 0)// 如果输入的值不合法,则抛出异常,让程序终止 throw new FuShuException("不能传入负数或者零"); this.r = r; } public double getMianJi() // throws Exception 此处不能抛异常,因为子类覆盖父类方法时, 只能抛父类异常的子类或者自己。如果父类没有抛出异常,那么子类也不可以抛 { return r * r * Math.PI; } } class ChangFangXing extends TuXing {// 长方形类 private double a, b; public ChangFangXing() { a = 1; b = 1; } public ChangFangXing(double a, double b) { if (a <= 0 || b <= 0)// 如果输入的值不合法,则抛出异常,让程序终止 throw new FuShuException("不能传入负数或者零"); this.a = a; this.b = b; } double getMianJi() // throws Exception 此处不能抛异常,因为子类覆盖父类方法时, // 只能抛父类异常的子类或者自己。如果父类没有抛出异常,那么子类也不可以抛 { return a * b; } } public class Demo { public static void main(String[] args) { TuXing t = new YuanXing(3); printMianJi(t); TuXing t1 = new ChangFangXing(12, -4);//此处传入了一个负数,会导致出现异常,使得程序终止 printMianJi(t1); /* 结果: 28.274333882308138 Exception in thread "main" FuShuException: 不能传入负数或者零 at ChangFangXing.<init>(Demo.java:60) at Demo.main(Demo.java:77) */ } public static void printMianJi(TuXing t) { System.out.println(t.getMianJi()); } }
总结:
异常是什么?是对问题的描述。将问题进行对象的封装。异常体系:
Throwable
++++|—–Errow
++++|—–Excepting
+++++++|—–RunTimeException
异常体系的特点:异常体系中的所有类以及建立的对象都具备可抛性。
也就是说可以被throw和throws关键字所操作。
只有异常体系具备这个特点。
throw和throws的用法:
throw定义在函数内,用于抛出异常对象。
throws定义在函数上,用于抛出异常类,可以抛出多个,用逗号隔开。
当函数内容有throw抛出异常对象,并未进行try处理。必须要在函数上声明,否则编译失败。
注意:RunTimeException除外。也就说,函数内如果抛出RunTimeException异常或者RunTimeException
异常的子类,函数上可以不用声明。
如果函数声明了异常,调用者需要进行处理。处理方式可以throws,可以try。
异常有两种:
编译时被检测异常
该异常在编译时,如果没有处理(没有throw也没有try),那么编译失败
该异常被标识,代表着可以被处理。
运行时异常(编译时不检测)
在编译时,不需要处理,编译器不检查。
该异常的发生,建议不处理,让程序停止。需要对代码进行修正。
注意:
1,finally中定义的通常是,关闭资源代码,因为资源必须要释放
2,finally只有一种情况不会执行。当程序执行到System.exit(0)时,fianlly不会执行。
//System.exit(0) –> 系统退出。jvm结束。
自定义异常:
定义类继承Exception或者RunTimeException
1,为了让自定义类具备可抛性。
2,让该类具备操作异常的共性方法。
/* 当要定义自定义异常的信息时,可以使用父类已经定义好的功能。 异常的异常信息传递给父类的构造函数 */ class MyException extends Exception{ public MyException(String string){ super(string); } }
异常的好处:
1,将问题进行封装。
2,将正常流程代码和问题处理代码相分离,方便与阅读。
异常的处理原则:
1,处理方式有两种:try 或者 throws。
2,调用到抛出异常的功能时,抛出几个,就处理几个(不要多处理或者少处理)
一个try对应多个catch。
3,多个catch中,父类的catch放到最下面。
4,catch内,需要定义针对性的处理方式,不要简单的定义printStackTrace,输出语句。
也不要不写。
//当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。 try{ throw new AException(); } catch(AException e){ throw e; }
/* 如果该异常处理不了,但并不属于该功能出现的异常。 可以将异常转换后,再抛出和该功能相关的异常。 或者异常可以处理,但需要将异常产生的和本功能相关的问题提供出去, 让调用者知道,并处理。也可以将捕获异常处理后,转换为新的异常。 */ try{ throw new AException(); } catch(AException e){ //对AException处理。然后再抛BException throw new BException(); }
在子父类覆盖时:
1,子类抛出的异常必须是父类异常的子类或者子集。
2,如果父类或者接口中没有异常抛出时,子类覆盖出现异常,只能try,不能抛
相关文章推荐
- 黑马程序员——java基础-多线程
- Android Java 程序员必备开发工具
- hadoop面试题总结2
- 一个平庸程序员自白:我不牛逼但那又怎样?
- 面试题杂货铺(四)
- 黑马程序员——java基础2
- Android Java 程序员必备开发工具
- 黑马程序员——java基础
- 面试题精解之一: 二叉树
- 二叉树中的那些常见的面试题
- 黑马程序员--If-else和switch语句
- 黑马程序员--Static的相关用法
- 黑马程序员--集合
- 黑马程序员--异常处理
- 总结的面试中常见65种应聘技巧回答
- 黑马程序员__java基础__函数、数组
- 程序员的思维修炼一些摘要
- 程序员保值的5个秘密
- 黑马程序员——java基础之集合类(二)
- 黑马程序员__java基础__常量、变量、运算符、语句