java学习笔记(二十二)异常

1、异常概念

指程序在执行过程中出现的非正常情况,会导致JVM的非正常停止,

异常本来是一个类,产生异常就是创建异常对象并抛出。

2、异常体系

最高父类throwable,子类error和exception

3、异常分类

运行期异常、编译期异常和错误

运行期异常可以不处理,默认让JVM终止程序

编译期异常必须处理

错误无法解决,必须修改代码

4、throw/throws关键字

异常处理常用到5个关键字

try

catch

finally

throw

throws

其中,throw关键字用于抛出异常(在方法内使用)

即方法内某语句可能异常时使用,可以把异常抛出给方法

方法在定义时要使用throws关键字接受方法内抛出的异常并再次抛出给方法调用者。

同理,如果是多级调用,每一级都要使用throws关键字接受并上抛(或者try/catch处理),最终抛出给main方法,在由main方法抛给jvm,最后中断程序。

注意:如果throw声明的方式运行期异常,可以不用throws上抛

private static int getElement(int[] arr,int index) {
        if(arr == null){
            throw new NullPointerException("传递的数组为空");
        }

        if(index<0 || index>arr.length-1){
            throw new ArrayIndexOutOfBoundsException("索引越界");
        }
        int ele = arr[index];
        return ele;

    }

如上,是执行参数合法性验证的代码,如果参数不符合要求,就会抛出空指针异常,但空指针异常时运行期异常,因此方法中不用使用throws关键字

5、Object非空判断

Object类中有一个方法可以很好的完成对参数是否为空的判断

public static <T> T rquireNonNull(T obj)//查看指定引用对象是不是null
//可以传递第二个参数,来实现异常触发时打印自定义的消息

示例:

public static void method(Object obj){
        //对传递进来的参数进行合法性判断,判断是否为null
//        if(obj==null){
//            throw new NullPointerException("空指针");
//
//        }
        //Objects.requireNonNull(obj);
        Objects.requireNonNull(obj,"空指针");


    }

注释中的代码与第八行的代码等效

6、异常处理的第一种方法,throws

前文说过,throws可以把异常交给调用者,这即是异常处理的第一种方法,交给别人处理

格式:

修饰符 返回值 方法名(形参表) throws XXXException{
	throw new XXXException("触发时四处的字符串");
}

即方法中声明一个Exception异常,方法声明是就要加上这个异常(方法内声明多个,throws也要声明多个)

注意:

​ 1、声明的对象必须是Exception或其子类

​ 2、如果抛出的多个异常中有继承关系,声明父类即可

​ 3、调用了声明抛出异常的方法就必须处理

 public static void reader(String filename) throws IOException {
        if (!filename.equals("c:\\\\a.txt")){
            throw new FileNotFoundException("找不到文件");
        }
        /**
         * 如果不是.txt结尾
         * 那么抛出IO异常对象
         */
        if (!filename.endsWith(".txt")){
            throw new IOException("文件类型错误");
        }
        System.out.println("没有问题");
    }

注意:main方法调用时也要处理异常,throws抛给虚拟机或者try/catch处理

7、异常处理的第二种方法、try/catch

try/catch可以捕获并处理异常

格式:

try{
	//可能出现异常的代码
}catch(定义代码变量 用来接收异常){
	//处理异常的代码
}

try中代码如果出现异常就会执行catch中的代码并继续执行程序。

public static void main(String[] args) {
        try {
                reader("d:\\a.tx");
        }catch (IOException e){//抛出什么异常,就定义什么异常
            System.out.println(e);
        }
            }
    public static void reader(String filename) throws IOException {
        if (!filename.endsWith(".txt")){
            throw new IOException("找不到文件");
        }
        System.out.println("没有问题");
    }

上面的代码,在reader方法中使用throws抛出方法,在main方法中捕获并处理,处理方法是打印该异常的信息

8、throwable类中的三种处理方法

/**
         * throwable类中定义了三个处理异常的方法
         * String toString() 返回此throwable的简短描述
         * String getMessage() 返回此throwable的详细消息字符串
         * String printStackTrace() JVM打印异常对象调用此方法,信息最全面
         *
         */

9、finally关键字

finally关键字和try/catch一起使用,finally代码块中的代码无论异常时候发生都会被执行。

格式:

	try{
          可能异常的代码
       }catch{
           异常处理
       }finally{
           无论是否出现异常,都会执行
       }

注意:

​ 1、finally关键字不能单独用

​ 2、finally一般用于资源回收

3、别再finally里写return,否则返回值就是finally里的内容

10、多异常捕获与处理

有三种处理思路

10.1、多个异常分别处理

try {
   	int[] arr = {1,2,3};
   	System.out.println(arr[3]);
}catch (ArrayIndexOutOfBoundsException e){
    System.out.println(e);
     }

即一个一个捕获和处理异常

10.2、多异常一次捕获,多次处理

即一次捕获所有异常,再挨个处理

try {
		int[] arr = {1,2,3};
		System.out.println(arr[3]);
		List<Integer> list = new ArrayList<>();
		list.add(1);
		list.add(2);
		list.add(3);
		System.out.println(list.get(3));
	}catch (ArrayIndexOutOfBoundsException e){
		System.out.println(e);
	}catch (IndexOutOfBoundsException e){
		System.out.println(e);
}

try中代码会产生两个异常,分别用两个catch处理

注意:多个catch中的异常对象如果有继承关系,子类一定要写上面

10.3、多异常一次捕获一次处理

	try {
            int[] arr = {1,2,3};
            System.out.println(arr[3]);
            List<Integer> list = new ArrayList<>();
            list.add(1);
            list.add(2);
            list.add(3);
            System.out.println(list.get(3));
        }catch (IndexOutOfBoundsException e){
            System.out.println(e);
        }
        System.out.println("后续代码");

一次捕获所有异常,再一次全部处理

11、父子类的异常

如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或是父类异常的子类或者不抛出
父类方法没有抛出异常,子类重写父类该方法时也不可能抛出异常,此时子类产生该异常,只能捕获,不能声明抛出

即父类的异常什么样,子类的异常就声明样

public class ZiFuExceptionDemo {
    public void show01() throws NullPointerException,ClassCastException{ }
    public void show02() throws IndexOutOfBoundsException{ }
    public void show03() throws IndexOutOfBoundsException{ }
    public void show04(){ }

}
class Zi extends ZiFuExceptionDemo{
    //子类重写父类方法时,抛出和父类相同的异常
    public void show01() throws NullPointerException,ClassCastException{ }
    //子类重写父类方法时,抛出父类异常的子类
    public void show02() throws ArrayIndexOutOfBoundsException{}
    //子类重写父类方法时,可以不抛出
    public void show03(){}
    //父类没抛异常,子类也不能抛,只能捕获
    public void show04(){}
}

12、自定义异常

自定义异常类供某些情况下使用

格式:

public class XXXException extends Exception/RuntimeException{
	添加一个空参构造
	添加一个带异常信息的构造
}

注意:

​ 1、自定义异常类一般以Exception结尾,说明该类是异常类

​ 2、必须继承Exception或RuntimeException

public class RegisterExceptionDemo9 extends Exception{
    //空参构造
    public RegisterExceptionDemo9() {
        super();
    }
    /**
     * 添加一个带异常信息的构造方法
     * 查看源码发现,所有异常类都有一个带异常信息的构造,方法内部会调用父类带异常信息的构造,让父类处理
     *
     */
    public RegisterExceptionDemo9(String message){
        super(message);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值