(*)异常:就是程序在运行时出现的不正常情况
//用面向对象的思想,把生活中的问题(不正常情况)也都归纳成类,这就是问题类的出现
//问题有两种:error和exception
//Java通过error类(严重的问题)来描述错误,对于error一般不编写针对型的代码对其进行处理
//Java通过exception类(轻微的问题)来描述异常,对于exception可以编写代码进行处理
//throwable类是error类和exception类的父类,throwable类也就是传说中的问题总类
(*)异常的处理:被catch就是被处理,或是继续声明异常。
//语句格式:
try
{
//需要被检测的代码
}
catch(异常类 变量)
{
//处理异常的代码;(处理方式)
}
finally
{
一定会执行的语句;
}
(*)对捕获到的异常对象进行常见的处理:
//就是3个常用的Exception类的方法:
getMessage():得到异常信息
toString():得到异常所属的类
printStackTrace():得到异常出现的位置
//jvm默认的异常处理机制,就是在调用printStackTrace方法,打印异常的详细信息
(*)throws关键字:写在有可能出异常的方法后面,叫做声明异常,调用此方法的地方就要使用try{}catch{}处理异常,也可以该方法继续throws抛出异常,最终抛给虚拟机。
如下,就是将异常抛给虚拟机:
1 class eccl 2 { 3 public static void main(String[] args) throws Exception 4 { 5 div d = new div(); 6 7 System.out.println(d.div(4,0)); 8 9 System.out.println("main"); 10 } 11 } 12 class div 13 { 14 int div(int a,int b) throws Exception 15 { 16 return a/b; 17 } 18 }
如下,就是对方法抛出的异常进行处理
1 class eccl 2 { 3 public static void main(String[] args) 4 { 5 div d = new div(); 6 try 7 { 8 System.out.println(d.div(4,0)); 9 } 10 catch (Exception e) 11 { 12 System.out.println("捕获异常"); 13 } 14 15 16 System.out.println("main"); 17 } 18 } 19 class div 20 { 21 int div(int a,int b) throws Exception 22 { 23 return a/b; 24 } 25 }
//不建议将异常抛给虚拟机,最好对声明的异常进行处理
(*)多异常处理,一个try跟多个catch
//函数当中如果有异常发生,这个函数的执行会立即终止,后面的语句不在执行
??//为什么当方法throws Exception时,调用该方法的地方没有处理,编译就不通过
??//而当方法throws ArithmeticException时或者ArrayIndexOutOfBoundsException时,调用该方法的地方没有处理,编译可以通过
1,声明异常时,建议声明更为具体的异常,这样处理的可以更具体
2,对方声明几个异常,就对应有几个catch
如果多个catch中的异常出现继承关系,父类异常catch放在最下面
//在进行catch处理时,catch中一定要定义具体处理方式
//正常情况下,处理异常就是把发生的异常用日志文件记录下来
(*)自定义异常:自定异常类,就是自定义一个Exception类的子类
//自定义异常类必须要手动抛出异常对象,就是throw new 自定义异常类();
//当手动抛出自定义异常类的对象时,一定要进行相对应的异常处理(方法声明异常或trycatch处理),否则编译不通过
//自定义异常练习,如下:
1 class demo1025 2 { 3 public static void main(String[] args) 4 { 5 ex a = new ex(); 6 int x=0; 7 try 8 { 9 x= a.div(100,-10); 10 System.out.println("jubux="+x); 11 } 12 catch(fushuException e)//捕捉自定义异常 13 { 14 System.out.println(e); 15 System.out.println("-------"+e.getValue()); 16 } 17 catch (ArithmeticException e) 18 { 19 System.out.println("-ArithmeticException catch code-"+e); 20 } 21 catch (ArrayIndexOutOfBoundsException e) 22 { 23 System.out.println("-ArrayIndexOutOfBoundsException catch code-"+e); 24 } 25 26 27 28 } 29 } 30 class ex 31 { 32 int div(int a,int b) throws fushuException 33 { 34 if(b<0) 35 { 36 throw new fushuException("被除数不能为负数",b);//抛出自定义异常 37 } 38 int[] arr = new int[a]; 39 System.out.println(arr[9]); 40 return a/b; 41 } 42 } 43 44 45 //自定义的异常类 46 class fushuException extends Exception 47 { 48 private int value; 49 fushuException(String message,int value) 50 { 51 super(message); 52 this.value = value; 53 } 54 public int getValue() 55 { 56 return this.value; 57 } 58 }
//throwable类就是可抛出类,只有throwable类和它的子类,可以被throws和throw两个关键字操作,也就是被抛出
//throws 和 throw的区别,throws是声明异常的,throw是抛出异常对象的
//可以声明多个异常,用“,”号隔开
(*)运行时异常runtimeException类极其子类的异常,不被处理,编译时不会报错,这就是运行时异常的特殊之处。而普通异常则必须被处理,否则编译报错。
当运行时异常出现时,程序必须停止,所以一般情况下没有对运行时异常进行处理的情况。
//所以自定义异常时,可以根据需要来自定义,普通异常或者运行时异常。
(*)finally关键字代码块:一定会执行的语句,一般用于关闭资源。
//即使try里有return语句(终止函数的关键字),return语句执行完毕后,还会再继续执行finally代码块的语句。
//有一种情况执行不到finally,就是System.exit(0),关闭jvm的语句。
(*)try代码块:
不在try块中,有异常,程序停止,虚拟机自动显示异常信息。其实就是虚拟机自动处理异常信息。
在try块中,有异常,异常后面的代码不再执行,虚拟机不自动显示异常信息。其实就是虚拟机不再自动处理异常信息
(*)异常在方法继承中的注意事项:
1,子类方法在覆盖父类方法时,如果父类方法抛出异常,那么子类的方法只能抛出父类方法抛出的异常,或是该异常的子类异常,或是不抛异常,如果不抛出异常则必须将父类抛出的异常在子类方法内部解决。
2,如果父类方法抛出多个异常,那么子类方法在覆盖时也可以抛出多个异常,但是要满足上一个条件。
3,如果父类方法或接口方法不抛出异常,那么子类方法在覆盖时也不可以抛出异常。如果子类方法确实产生异常,则必须在该子类方法内部将异常进行处理。
(*)异常小练习:
1 class yichang1027 2 { 3 public static void main(String[] args) 4 { 5 rect r=null; 6 r = new rect(-10,10); 7 System.out.println(r.area()); 8 } 9 } 10 abstract class area 11 { 12 abstract int area(); 13 } 14 class rect extends area 15 { 16 int length; 17 int width; 18 rect(int length,int width) 19 { 20 if(length <= 0 || width <= 0) 21 throw new NoValueException("不能为负数"); 22 this.length = length; 23 this.width = width; 24 } 25 int area() 26 { 27 return this.length*this.width; 28 } 29 } 30 class NoValueException extends RuntimeException//或是Exception,区分继承不同异常父类后的区别 31 { 32 NoValueException(String msg) 33 { 34 super(msg); 35 } 36 }
RuntimeException运行时异常,发生时,程序必须要停,运行时异常是一个严重的异常,一般情况下都要停下来,并不是程序代码错误出的异常,而是进行运算的参数不符合规矩。运行时异常。
1 class yichang1027 2 { 3 public static void main(String[] args) 4 { 5 rect r=null; 6 7 //r = new rect(-10,10); rect构造函数抛出的异常没有被处理,程序出异常而终止 8 9 try 10 { 11 //rect构造函数抛出的异常被处理了,就执行最后一句System.out.println(r.area()); 12 r = new rect(-10,10); 13 } 14 catch (NoValueException e) 15 { 16 17 } 18 System.out.println(r.area()); 19 } 20 } 21 abstract class area 22 { 23 abstract int area(); 24 } 25 class rect extends area 26 { 27 int length; 28 int width; 29 rect(int length,int width) 30 { 31 if(length <= 0 || width <= 0) 32 throw new NoValueException("不能为负数"); 33 this.length = length; 34 this.width = width; 35 } 36 int area() 37 { 38 return this.length*this.width; 39 } 40 } 41 class NoValueException extends RuntimeException//或是Exception,区分继承不同异常父类后的区别 42 { 43 NoValueException(String msg) 44 { 45 super(msg); 46 } 47 }
普通异常在编译时被检测,运行时异常不被检测。
(*)异常的好处:
1,将问题进行封装
2,将正常流程代码和问题处理代码分离
(*)异常的处理原则:
1,处理方式:try或者继续throws
2,调用抛出异常的功能时,有几个抛出,就做几个catch
3,当多个catch时,父类catch放下面
4,catch内,需要定义针对性的处理方式,不要只写一句简单的输出语句或是什么也不写。
5,当捕获到的异常,处理不了时,可以继续在catch中抛出。 如果该异常处理不了,但并不属于该功能出现的异常,可以将异常转换后,在抛出和该功能相关的异常。
或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,让调用者知道,并处理,也可以将捕获异常处理后,抓换成新的异常再抛出。
(*)异常的注意事项:
1,子类方法在覆盖父类方法时,如果父类方法抛出异常,那么子类的方法只能抛出父类方法抛出的异常,或是该异常的子类异常,或是不抛异常,如果不抛出异常则必须将父类抛出的异常在子类方法内部解决。
2,如果父类方法抛出多个异常,那么子类方法在覆盖时也可以抛出多个异常,但是要满足上一个条件。
3,如果父类方法或接口方法不抛出异常,那么子类方法在覆盖时也不可以抛出异常。如果子类方法确实产生异常,则必须在该子类方法内部将异常进行处理。