0202异常
1、异常继承体系
Exception异常类继承Throwable
Throwable中有两个子类:error类 Exception类
error:癌症,不能处理,只能程序猿改代码
exception:1.运行期异常:癌症,不能处理,只能程序猿改代码2.编译期异常:感冒,是可以处理的
Exception子类中有常用子类有:RuntimeException类,SQLException类等等
(1)error异常举例
public class Demo02 { public static void main(String[] args) { int[] arr=new int[1000000000]; } } Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at com.oracle.demo01.Demo02.main(Demo02.java:8)
此时程序运行会报出Error异常,不允许这个存在,只能程序员改代码
(2)Exception异常
(2-1)运行期异常
public class Demo3 { public static void main(String[] args) throws NullPointerException,ArrayIndexOutOfBoundsException{ // TODO Auto-generated method stub int[] arr={1,2,3}; int n=get(arr); System.out.println(n); } public static int get(int[] arr)throws NullPointerException,ArrayIndexOutOfBoundsException{ if(arr==null){ throw new NullPointerException("数组为空!"); } //如果arr.length小于等于3 if(arr.length<=3){ //抛出异常 throw new ArrayIndexOutOfBoundsException(arr.length+":数组长度不够"); } int num=arr[3]; return num; } } Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3:数组长度不够 at com.oracle.demo01.Demo3.get(Demo3.java:18) at com.oracle.demo01.Demo3.main(Demo3.java:8)
我在get方法中抛出了两个异常,抛给调用者,调用者可以选择处理和不处理,此时不处理,则继续将异常往上抛,抛给jvm虚拟机,虚拟机首先终止程序,并且红字打印异常信息。
注:可以同时抛出多个异常信息。
图解:
(2-2)编译期异常
public class Demo05 { public static void main(String[] args) { // TODO Auto-generated method stub int[] arr={1,2,3}; try{ int n=get(arr); System.out.println(n); }catch(Exception ex){ ex.printStackTrace(); }finally{ System.out.println("这是不管有没有异常都走的语句"); } System.out.println(“hello”); } public static int get(int[] arr)throws Exception{ if(arr==null){ throw new NullPointerException("数组为空!"); } if(arr.length<=3){ throw new Exception("数组长度不够"); } int num=arr[3]; return num; } }
编译期异常,就是当异常抛出,抛给调用者,调用者选择不往jvm虚拟机抛,选择自己捕获异常并解决异常。运用了try..catch..finally语句
try..catch..finally:try将可能发生异常的语句包起来,catch,将处理语句包起来,finally,是不管有没有异常都走这条语句
格式:
try {
//需要被检测的语句。
}
catch(异常类 变量) { //参数。
//异常的处理语句。
}
finally {
//一定会被执行的语句。
}
这条语句有很多个组合方法:(1)try..catch .finally(2)try...多个catch(3)try...finally
在catch语句中,还可以有多个方法:例:
System.out.println(ex.getMessage());
System.out.println(ex.toString());
2、异常继承问题
父类抛异常子类继承父类只能抛小于等于父类的异常
父类方法如果没有抛异常子类重写后也不能抛异常
子类调用有异常的方法只能try catch处理,不能抛
代码展示
创建父类
public class Fu { public void eat()throws SQLException{ } public void sleep(){ } }
创建子类
public class Zi extends Fu { @Override//父类抛异常子类继承父类只能抛小于等于父类的异常 public void eat() throws SQLDataException { } @Override//父类方法如果没有抛异常子类重写后也不能抛异常 public void sleep() {//子类调用有异常的方法只能try catch处理,不能抛 try { eat(); } catch (SQLDataException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
3、自定义异常
自定义一个异常类,继承Exception或者runtimeException都可以
因为在抛异常的时候是调用的异常类的构造方法,所以要在自定义类中创建空参构造和有参构造,并且要写super语句将有参构造中的参数传进来。
代码展示:
创建自定义异常类
public class FushuException extends Exception { public FushuException(){ } public FushuException(String mes){ super(mes); } }
创建测试类
public class Demo07 { public static void main(String[] args) { // TODO Auto-generated method stub int[] arr={11,-22,66,44}; try { System.out.println(avg(arr)); } catch (FushuException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static double avg(int[] arr)throws FushuException { double sum=0; for(int i:arr){ if(i<0){ throw new FushuException("值为负数:"+i); } sum+=i; } return sum/arr.length; } }
4、异常类实例
public class Demo06 { public static void main(String[] args) { // TODO Auto-generated method stub SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); //z字符串转日期对象 try { Date d=sdf.parse("2020-02-02"); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
上述例子中用try..catch解决了异常,
原理就是当调用prase方法的时候,这个prase方法抛出了一个编译期异常praseException。如果不用try..catch解决就得继续往上抛,在main方法后加throws praseException 也可以