day12 异常
概述
异常 指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
注意
异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.
异常的体系
Error : 严重错误,无法通过处理解决的错误
Exception异常:异常产生后程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的
异常(Exception)的分类
【编译时期】 和 【运行时期】 异常
-
编译时期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)
-
运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)
异常处理方式
JVM默认处理异常的方式
==如果程序出现了问题,我们没有做任何处理,最终JVM 会做默认的处理,==
-
处理方式有如下两个步骤:
-
把异常的名称,错误原因及异常出现的位置等信息输出在了控制台
-
程序停止执行
-
try-catch方式处理异常
定义格式
try { 可能出现异常的代码; 正常代码啊//不会再执行 } catch(异常类名 变量名) { 异常的处理代码; }
执行流程
-
程序从 try 里面的代码开始执行
-
出现异常,就会跳转到对应的 catch 里面去执行
-
执行完毕之后,程序还可以继续往下执行
两个异常
public static void main(String[] args) { System.out.println("我在前面执行"); int a = 1; int b = 0; int[] arr = {1,2,3}; try { System.out.println(arr[4]);//出错 System.out.println(a/b); } catch (ArithmeticException e) { e.printStackTrace(); System.out.println("除数不能为0"); } catch (IndexOutOfBoundsException e2){ e2.printStackTrace(); System.out.println("你访问的脚标已超出!!"); } System.out.println("我在后面执行"); }
Exception大的异常
public static void main(String[] args) { System.out.println("我在前面执行"); int a = 1; int b = 0; int[] arr = {1,2,3}; try { System.out.println(arr[4]);//出错 System.out.println(a/b); } catch (Exception e) {//抓取最大异常,但并不明确异常类型 e.printStackTrace(); System.out.println("有问题"); } System.out.println("我在后面执行"); }
注意事项
/** * 1:能明确的尽量明确,不要用大的来处理。 * 2:平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。 */ public static void main(String[] args) { int a = 1; int b = 0; int[] arr = {1,2,3}; try { System.out.println(arr[4]); System.out.println(a/b); } catch (ArithmeticException e) { //平级关系的异常谁前谁后无所谓 e.printStackTrace(); System.out.println("除数不能为0"); } catch (IndexOutOfBoundsException e2){ //平级关系的异常谁前谁后无所谓 e2.printStackTrace(); System.out.println("你访问的脚标已超出!!"); } catch (Exception e3){ //大的异常类型放在最后面 e3.printStackTrace(); System.out.println("有问题"); } }
/** * try..catch (ArithmeticException | IndexOutOfBoundsException e){} * 注意:这个方法虽然简洁,但是也不够好。 * A:处理方式是一致的。(实际开发中,好多时候可能就是针对同类型的问题,给出同一个处理) * B:多个异常间必须是平级关系 */ public static void main(String[] args) { int a = 1; int b = 0; int[] arr = {1,2,3}; try { System.out.println(arr[4]); System.out.println(a/b); } catch (ArithmeticException | IndexOutOfBoundsException e) { e.printStackTrace(); System.out.println("除数不能为0"); } }
try中的变量作用只能作用在try中的代码块中
throws 处理方式
什么是throws处理
用在方法的声明上,一般是自己解决不了的问题,直接抛给调用者解决
声明异常格式
修饰符 返回值类型 方法名() throws 异常类名 {} //一般使用准确的异常类型 ,也可以同时抛出多个类型 当一个方法可能抛出多个异常时,可以使用throws关键字将这些异常列在方法签名中。关于父类异常和子类异常的顺序,按照规则应该将父类异常放在子类异常之后。
throw 处理方式
抛出一个异常对象,一次只能抛出一个,但是可以分多次进行抛出
他的处理原理和jvm机的处理原理一样,第一步给出详细的异常信息,第二步停止程序的正常运行
区别:它可以通过给抛出异常对象有参构造传入想要输出的字符串,在控制台输出来
定义格式
修饰符 返回值类型 方法名(参数列表) { if (判断条件) { throw new 异常对象("异常的原因"); } }
throw 与 throws的区别
1.throw代表动作,表示抛出一个异常的动作; throws代表一种状态,代表方法可能有异常抛出 2.throw用在方法实现中,而throws用在方法声明中 3.throw只能用于抛出一种异常,而throws可以抛出多个异常
Throwable类中常见方法
Throwable 是异常的根类
常用的方法
String getMessage() 获取的异常的原因
String toString() 获取的是异常的类型和原因
void printStackTrace() 获取的是异常的类型 原因 和位置
finally 代码块
无论try 和 catch 中的代码是否执行 finally 中的代码都要执行
如果在finally之前有return
即使finally前有return,finally也要在return之前执行
自定义异常
为什么要自定义异常
在开发中总是有些异常情况是SUN没有定义好的,此时我们根据自己业务的异常情况来定义异常类
一个类继承了java.lang.Exception 类 她就成了编译异常类
一个类继承了`java.lang.RuntimeException类 她就成了运行时异常类
自定义异常类的定义格式
public class RegistException extends RuntimeException { public RegistException() { } public RegistException(String message) { super(message); } }
final,finally和finalize的区别
final:最终的意思,可以修饰类,成员变量,成员方法 修饰类,类不能被继承 修饰变量,变量是常量 修饰方法,方法不能被重写 finally:是异常处理的一部分,一般用于释放资源。 一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了 finalize:是Object类的一个方法,用于垃圾回收,在调用GC方法之前会执行,从下向上执行finalize方法