一、异常处理
异常出现后 程序就直接结束了 异常后面的语句就不执行了 想办法让异常不发生 或者 异常发生后继续去执行
-
修改代码检测异常
-
发生异常后捕获并处理异常
二、异常的继承体系结构
Throwable类是java中所有异常和错误的超类
三、错误 Error
Error:错误 严重问题 会导致JVM虚拟机崩溃或者是代码直接无法运行
-
一般无法捕获处理的 需要修改代码或修改环境避免
-
StackOverflowError:栈溢出
-
OutOfMemoryError:内存溢出 堆
-
NoClassDefFoundError:找不到类 没有找到字节码文件
四、异常 Exception
Exception:在代码运行时发生的一些不正常的情况
-
受检异常:这种异常必须在编译时就进行捕获
-
非受检异常:通常这种是通过修改代码或逻辑去避免的异常
编译时异常:编译阶段就要进行处理的异常
运行时异常:RuntimeException及其子类,编译阶段不需要处理。代码运行时出现的异常
五、异常处理
1.jvm默认的处理方式
-
把异常的名称,异常原因及异常出现的位置信息输出在了控制台
-
程序停止执行,下面的代码就不会再执行了
public static void main(String[] args) {
System.out.println("dsrg");
System.out.println(2/0);
System.out.println("dghjt");
System.out.println("fdzfgt");
}
--------------------------
dsrg
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.hqyj.Exception.ExceptionTest.main(ExceptionTest.java:46)
2.自己处理(捕获异常)
try catch 语句(ctrl+alt+v :快捷生成try catch)自动补全:ctrl+v
-
可以写多个catch 去捕获多个异常 如果先捕获了父类异常 子类异常就会报错
-
finally{} finally里面的内容无论是否发生异常会被执行
try{ // 可能出现异常的代码 }catch(异常类型1 异常的变量名1){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }
public static void main(String[] args) { int[] arr ={1,2,34,5}; try { //可能出现异常的代码 System.out.println(arr[10]); //此处出现了异常,程序就会再这里创建一个ArrayIndexOutOfBoundsException对象(控制台会提示) //new ArrayIndexOutOfBoundsException() //拿着这个对象到catch的小括号中对比,看括号中的变量是否可以接收这个变量 //当catch里面所有的代码执行完毕,继续执行try catch体系下的其他代码 }catch (ArrayIndexOutOfBoundsException e){//捕获异常 System.out.println("索引越界了");//打印出异常的类型、性质以及在程序中出 //现的位置 } System.out.println("看看我执行了吗?"); }
3.捕获异常灵魂四问:
-
灵魂一问:如果try总没有遇到问题,怎么执行?
会把try中的代码全部执行完毕,不会执行catch里面的代码
注意:只有出现了异常才会执行catch里面的代码
-
灵魂二问:如果try中遇到了多个问题,怎么执行?
会写多个catch与之对应
注意:如果我们要捕获多个异常,这些异常存在父子关系的话,那么父类一定要写在下面
try { //可能出现异常的代码 System.out.println(arr[10]);//ArrayIndexOutOfBoundsException System.out.println(2/0);//ArithmeticException String s = null;//NullPointerException }catch (ArrayIndexOutOfBoundsException e){ System.out.println("索引越界了"); System.out.println("除数不能为0"); System.out.println("空指针异常"); } System.out.println("看看我执行了吗?"); }
-
灵魂三问:如果try中的问题没有被捕获,怎么执行?
相当于try catch的代码白写了,最终还是会交给虚拟机进行处理
-
灵魂四问:如果try中遇到了问题,那么try下面的其他代码还会执行吗?
下面的代码不会执行了,直接跳转到对应的catch当中,执行catch里面的语句体
但是如果没有对应的catch与之匹配,那么还是会交给虚拟机进行处理
/*如果try语句块中发现了异常,代码并不会继续往下去执行,此时会抛出一个相应的 异常对象, catch语句就会根据抛出的异常类型是否匹配进行捕获并处理,并开始执 行catch语句块中的代码,执行完后代码继续往下执行。 如果try语句块中没有发生异常,那么try语句块中的代码肯定正常执行结束。此时 catch语句不会执行。代码跳过catch语句块继续往下去执行。*/
catch中声明的异常能够捕获到它的子异常。当捕获的多个异常类之间存在父子关系 时,捕获异常时一般先捕获子类,再捕获父类。所以子类异常必须在父类异常的前 面,否则子类捕获不到。所以说,无论如何finally语句中的代码都会执行,如果finally语句中有 return语句,永远返回finally中rerurn的结果。4.抛出处理
-
throws/throw 关键字的区别:
-
throws:写在方法定义处,表示声明一个异常,告诉调用者,使用本方法可能会有哪些异常
throw:写在方法内,结束方法,手动抛出异常对象,交给调用者,方法下面的代码就不执行了
throws表示出现异常的一种可能性,并不是一定会发生异常,表明一旦发生异常我 不处理,交给调用该方法的地方去处理。但throw一旦声明就明确在这里要抛出异 常。
-
如果一个方法没有捕获一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关 键字放在方法签名的尾部。也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚 捕获到的。
-
下面方法的声明抛出一个 RemoteException 异常:
-
public static void main(String[] args) throws InterruptedException { Thread.sleep(123); }
-
/* 需求:定义一个方法求数组的最大值 */ public static int getMax(int[] arr){ if (arr == null){ //手动创建一个异常对象,并把这个异常交给方法的调用者处理 //此时方法就会结束,下面的代码不会再执行了 throw new NullPointerException(); } if (arr.length ==0) { //手动创建一个异常对象,并把这个异常交给方法的调用者处理 //此时方法就会结束,下面的代码不会再执行了 throw new ArrayIndexOutOfBoundsException(); } int max = arr[0]; for (int i = 1; i <arr.length ; i++) { if (arr[i]>max){ max = arr[i]; } } return max; }
子类再重写父类方法时,子类重写后的方法声明抛出的异常类型应该和父类方法声明 抛出的异常一致或者是其子类。
父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异 常,只能捕获处理,不能声明抛出。
//父类 public class Father { public void method() throws ParseException{ System.out.println("抛出一个ParseException,交给儿子处理"); } } //子类 class Son extends Father { @Override public void method() throws Exception{ //报错!!!!!!!!!!,不能抛一个比父类中的方法还大的异常 System.out.println("不但不处理,还要抛一个更大的异常"); } }
总结:
-
虚拟机默认处理异常的方式
-
把异常信息以红色字体打印在控制台,并结束程序
-
捕获:try catch
一般用在调用处,能让代码继续往下允许
-
抛出:throw throws
在方法中,出现异常了。
方法就没有继续运行下去的意义了,采取抛出处理
让该方法结束运行并告诉调用者出现了问题
-
定义异常类(为了让控制台的报错信息更加的见名知意)
-
写继承关系
-
空参构造
-
带参构造
-
(空参构造和带参构造在这个自定义异常类中用Generate生成,继承关系则是 继承Exception或者RuntimeException)
-
自定义异常
-
定义异常类(为了让控制台的报错信息更加的见名知意)
-
写继承关系
-
(空参构造和带参构造在这个自定义异常类中用Generate生成,继承关系则是 继承Exception或者RuntimeException)
-
空参构造
-
带参构造
-