异常概念:
就是程序中出现的不正常的现象(错误与异常)(代码在运行时候出现问题)
异常的继承体系:
Throwable: 它是所有错误与异常的超类(祖宗类)
|- Error 错误,修改java源代码
|- Exception 编译期异常, javac.exe进行编译的时候报错
|- RuntimeException 运行期异常, java出现运行过程中出现的问题
异常处理的两种方式:
1,出现问题,自己解决 try…catch…finally
try{ 可能出现异常的代码 } catch(异常类名 对象名){ 异常处理代码 } finally { 异常操作中一定要执行的代码 }
2,出现问题,别人解决 throws
格式: 修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2,...{} public void method() throws Exception{}
异常分类
异常的根类是Throwable,其下有两个子类:Error与Exception,平常所说的异常指Exception。
严重错误Error,无法通过处理的错误
编译时异常Exception,编译时无法编译通过。如日期格式化异常
运行时异常RuntimeException,是Exception的子类,运行时出现错误不用声明可直接throw new,直接修改代码
try catch 后的代码,需要运行时,用Execption
不需要运行时用RuntimeExecption
异常基本操作
1、创建异常对象
2、抛出异常
3、处理异常:
捕获处理,将异常获取,使用try/catch做分支处理
try{ 需要检测的异常; } catch(异常对象) { 通常我们只使用一个方法:printStackTrace打印异常信息 }
代码实现:
1 public class Demo03 {
2 /*try{
3 可能会发生异常的代码
4 }catch(异常对象 ex){
5 处理语句
6 }finally{
7 不管出不出现异常不许执行语句
8 一般写释放资源的语句
9 }
10 */
11 public static void main(String[] args) {
12 int[] arr={1,2,3};
13 try{
14 //try中一旦发生异常,try范围内的下面代码将不再执行
15 int index=get(arr);
16 System.out.println(index);
17 }catch(NullPointerException ex){
18 System.out.println(ex);
19 }catch(Exception ex){
20 System.out.println(ex);
21 }finally{
22 System.out.println("这是一定会被执行的语句");
23 }
24 System.out.println("aaa");
25 }
26 public static int get(int[] arr) throws NullPointerException,Exception{
27 if(arr==null){
28 throw new NullPointerException("数组为空");
29 }
30 if(arr.length<4){
31 throw new Exception("数组长度不够");
32 }
33 return arr[3]+1;
34 }
35
36 }
finally中的语句时无论是否出现异常都必须会执行的语句,只用来释放资源
注意:子类异常不能大于父类异常
这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常的关系,
那么子类异常要求在上面的catch处理,父类异常在下面的catch处理。
声明抛出处理,出现异常后不处理,声明抛出给调用者处理。
方法声明上加throws 异常类名
注意:异常的处理,指处理异常的一种可能性,即有了异常处理的代码,不一定会产生异常。
如果没有产生异常,则代码正常执行,如果产生了异常,则中断当前执行代码,执行异常处理代码。
异常注意事项
多异常处理
捕获处理:
1多个异常可以分别处理
2多个异常一次捕获多次处理
3多个异常一次捕获,采用同一种方式处理
声明抛出异常:
声明上使用,一次声明多个异常
自定义异常
如果Java没有提供你需要的异常,则可以自定义异常类。
定义方法:编译时异常继承Exception,运行时异常继承RuntimeException
代码实现:
public class FuShuExecption extends RuntimeException { FuShuExecption(){ } FuShuExecption(String str){ super(str); } } public class Demo08 { public static void main(String[] args) { double a=avg(89.3,-45,77,66,88); System.out.println(a); } //我要写一个方法计算学生的平均成绩 //FuShuExecption public static double avg(double...score){ double sum=0; for(double s:score){ if(s<0){ throw new FuShuExecption("负数异常"+s); } sum=sum+s; } return sum/score.length; } }
异常的产生过程解析
代码实现:
1 //错误: java.lang.OutOfMemoryError 内存溢出错误
2 //错误Error:癌,艾滋,白血病 无药可治,程序员无法处理,只能修改代码
3 //异常Exception:感冒 发烧 可以处理的
4 //int[] arr=new int[888888888];
5 public class Demo01 {
6
7 public static void main(String[] args) {
8 int[] arr={5,2,1};
9 get(arr);
10
11 }
12 public static int get(int[] arr){
13 return arr[3]+1;
14 }
15
16 }
图解:
异常在方法重写中细节
运行时异常被抛出可以不处理。即不捕获也不声明抛出
如果父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集
父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
当多异常处理时,捕获处理,前边的类不能是后边类的父类
代码举例:
1 public abstract class Demo06 {
2
3 public abstract void eat();
4
5 }
6 class Zi extends Demo06{
7 //如果父类方法抛出异常,子类重写后的方法有两种选择:
8 //1.不抛异常
9 //2.抛异常,但是异常类型不能超越父类异常
10 //如果父类没有异常,子类重写后不能抛出异常
11 //但是如果重写后的方法中调用了抛出异常的方法,只有一种解决方法
12 //就是 trycatch
13 public void eat() {
14 try {
15 work();
16 } catch (Exception e) {
17 // TODO Auto-generated catch block
18 e.printStackTrace();
19 }
20
21 }
22 public void work() throws Exception{
23
24 }
25 }
当被覆盖的方法没有异常声明时,子类覆盖时无法声明异常的。
class Fu {
public void method (){
}
}
class Zi extends Fu {
public void method() throws Exception { }//错误的方式
}
异常中常用方法
getMassage() | 打印异常信息 | |
toString() | 打印异常类名和异常信息 | |
printStackTrace() | 打印异常详细信息 |
代码举例:
1 public class Demo07 {
2
3 public static void main(String[] args) {
4 int[] arr=null;
5 try {
6 int index=get(arr);
7 } catch (Exception e) {
8 //e.printStackTrace();//打印异常详细信息
9 //System.out.println(e.toString());//异常类名和异常信息
10 System.out.println(e.getMessage());//打印异常信息
11 }
12
13 }
14 public static int get(int[] arr) throws Exception{
15 if(arr==null){
16 throw new Exception("数组为空");
17 }
18 return arr[2];
19 }
20
21 }