16 - 异常
1.异常:就是程序中出现的不正常的现象(错误与异常) 异常的继承体系: 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的子类,运行时可能会报错,可以不处理。如空指针异常 异常基本操作 创建异常对象 抛出异常 处理异常: 捕获处理,将异常获取,使用try/catch做分支处理 try{ 需要检测的异常; } catch(异常对象) { 通常我们只使用一个方法:printStackTrace打印异常信息 } 声明抛出处理,出现异常后不处理,声明抛出给调用者处理。 方法声明上加throws 异常类名 注意:异常的处理,指处理异常的一种可能性,即有了异常处理的代码,不一定会产生异常。如果没有产生异常,则代码正常执行,如果产生了异常,则中断当前执行代码,执行异常处理代码。 异常注意事项 多异常处理 捕获处理: 1多个异常可以分别处理 2多个异常一次捕获多次处理 3多个异常一次捕获,采用同一种方式处理 声明抛出异常: 声明上使用,一次声明多个异常 运行时异常被抛出可以不处理。即不捕获也不声明抛出 如果父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集 父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出 当多异常处理时,捕获处理,前边的类不能是后边类的父类 自定义异常: 如果Java没有提供你需要的异常,则可以自定义异常类。 定义方法:编译时异常继承Exception,运行时异常继承RuntimeException。
package cn.itcast.demo; /* * 异常中的关键字 * throw,在方法内部,抛出异常的对象 * throw 后面,必须写new 对象,必须是异常的对象,必须是Exception或者子类 * * 方法中声明异常关键字 * throws 用于在方法的声明上,标明次方法,可能出现异常 * 请调用者处理 * throws 后面必须写异常类的类名 * * 调用了一个抛出异常的方法,调用者就必须处理 * 不处理,编译失败 */ public class ExceptionDemo { public static void main(String[] args) throws Exception { int[] arr = {}; int i = getArray(arr); System.out.println(i); } //对数组的最后索引*2,返回 public static int getArray(int[] arr) throws Exception { //对方法参数进行合法性的判断,进行判断是不是null if( arr == null){ //抛出异常的形式,告诉调用者 //关键字 throw throw new Exception("传递数组不存在"); } //对数组进行判断,判断数组中,是不是有元素 if(arr.length == 0){ //抛出异常的形式,告诉调用者,数组没有元素 throw new Exception("数组中没任何元素"); } int i = arr[arr.length-1]; return i*2; } }
package cn.itcast.demo; /* * 异常的处理方式: * try...catch...finally * 格式: * try{ * 被检测的代码 * 可能出现异常的代码 * }catch(异常类名 变量){ * 异常的处理方式 * 循环,判断,调用方法,变量 * }finally{ * 必须要执行代码 * } */ public class ExceptionDemo1 { public static void main(String[] args) { int[] arr = null; try{ int i = getArray(arr); System.out.println(i); }catch(NullPointerException ex){ System.out.println("###"+ex); }catch(ArrayIndexOutOfBoundsException ex){ System.out.println("!!!!!!"+ex); } System.out.println("Game Over"); } /* * 定义方法,抛出异常 * 调用者使用try catch */ public static int getArray(int[] arr)throws NullPointerException,ArrayIndexOutOfBoundsException{ //对数组判空 if( arr == null){ //手动抛出异常,抛出空指针异常 throw new NullPointerException("数组不存在"); } //对数组的索引进行判断 if( arr.length < 3){ //手动抛出异常,抛出数组的索引越界异常 throw new ArrayIndexOutOfBoundsException("数组没有3索引"); } return arr[3]+1; } }
package cn.itcast.demo; /* try{ * 被检测的代码 * 可能出现异常的代码 * }catch(异常类名 变量){ * 异常的处理方式 * 循环,判断,调用方法,变量 * }finally{ * 必须要执行代码 * } * finally,无论程序是否有异常出现,程序必须执行 * 释放资源 */ public class ExceptionDemo3 { public static void main(String[] args) { try{ function(0); }catch(Exception ex){ System.out.println(ex); }finally{ System.out.println("代码必须执行"); } } public static void function(int a)throws Exception{ if( a == 0) throw new Exception(); System.out.println(a); } }
package cn.itcast.demo1; /* * 异常分为编译异常和运行时期异常 * 编译异常: 调用了抛出异常的方法,不处理编译失败 (try throws) * 运行异常: 抛出的异常是RuntimeException类,或者是他的子类 * * 运行异常的特点: * 方法内部抛出的异常是运行异常, new XXXException * 方法的声明上,不需要throws语句,调用者,不需要处理 * 设计原因: * 运行异常,不能发生,但是如果发生了,程序人员停止程序修改源代码 * * 运行异常: 一旦发生,不要处理,请你修改源代码, 运行异常一旦发生,后面的代码没有执行的意义 */ public class RuntimeExceptionDemo { public static void main(String[] args) { double d = getArea(1); System.out.println(d); } /* * 定义方法,计算圆形的面积 * 传递参数0,或者负数,计算的时候没有问题 * 但是,违反了真实情况 * 参数小于=0, 停止程序,不要在计算了 */ public static double getArea(double r){ if(r <= 0) throw new RuntimeException("圆形不存在"); return r*r*Math.PI; } public static void function(){ int[] arr = {1,2,3}; //对数组的5索引进行判断,如果5索引大于100,请将5索引上的数据/2,否则除以3 //索引根本就没有 if(arr[5] > 100){ arr[5] = arr[5]/2; }else{ arr[5] = arr[5]/3; } } }
package cn.itcast.demo2; /* * Throwable类中的方法 * 三个方法,都和异常的信息有关系 * String getMessage() 对异常信息的详细描述 异常了! * String toString() 对异常信息的简短描述 java.lang.Exception: 异常了! * void printStackTrace() 将异常信息追踪到标准的错误流 异常信息最全,JVM默认调用方法也是这个方法 */ public class ExceptionDemo1 { public static void main(String[] args) { try{ function(); }catch(Exception ex){ //System.out.println(ex.toString()); ex.printStackTrace(); } } public static void function() throws Exception{ throw new Exception("异常了!"); } }
自定义异常
package cn.itcast.demo3; /* * 自定义异常 * 继承Exception,或者继承RuntimeException * 构造方法中,super将异常信息,传递给父类 */ public class FuShuException extends RuntimeException{ public FuShuException(String s){ super(s); } public FuShuException(){} }
package cn.itcast.demo3; public class ExceptionDemo { public static void main(String[] args) { int avg = getAvg(50,60,-70,80); System.out.println(avg); } /* * 传递成绩,计算成绩的平均数 * 成绩没有负数,需要抛出异常,停止运算 */ public static int getAvg(int...source){ int sum = 0 ; for(int s : source){ if( s < 0){ throw new FuShuException("成绩错误 "+s); } sum = sum + s; } return sum/source.length; } }