Java 异常

防御式编程

两种主要方式:

LBYL:Look Before You Leap. 在操作之前就做充分的检查。

EAFP:It’s Easier to Ask Forgiveness than Permission."事后获取原谅比事前获取许可更容易."也就是先操作,遇到问题再处理。

在Java中异常的核心思想是EAFP。

LBYL风格的代码 :

//假设是一个登陆游戏
boolean ret=false;
if(!ret){
    //处理登陆游戏错误
    return;
}
if(){
    //......
}

这种通过if语句处理异常的方法通常在C++中使用。

EAFP风格的代码:

private static String username="byte";
private static String password="12345";
public static void main(String[] args) {
    int count=0;
    Scanner scanner=new Scanner(System.in);

        String u=scanner.next();
        String p=scanner.next();
        try{
            login(u,p);
        }catch (UserError userError){
            userError.printStackTrace();
        }catch (PasswordError passwordError){
            passwordError.printStackTrace();
        }

}

EAFP风格是通过try-catch捕获异常。

异常的基本用法

基本语法:

try{
可能出现异常的代码块;
}catch(异常类型 异常对象){
处理异常;
}finall{
异常的出口;
}
  • try中放的是可能出现异常的代码块。
  • catch中放的是出现异常时如何处理异常。
  • finally中的代码块是用于处理善后工作,会在最后执行。
  • 其中catch和finally可以选择加上也可以选择不加上。

代码示例:

public static void main(String[] args) {
    int[] arr={1,2,3};
    try {
        System.out.println("before");
        arr=null;
        System.out.println(arr[100]);
        System.out.println("after");
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        System.out.println("finally code");
    }

}

在这里插入图片描述

在上述代码中以及运行结果我们可以看出在try代码块中只执行了前两行代码,而运行结果中报出了空指针异常,这也就代表了执行到了try中第二行代码时发生了异常因此就直接进入catch中的处理异常,这里处理异常的方式是直接将异常打印出来,最后还执行了finally中的代码块。

从上我们可以 看出finally代码块是一定会执行的。

异常处理流程

  • 程序先执行 try 中的代码。
  • 如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配。
  • 如果找到匹配的异常类型, 就会执行 catch 中的代码。
  • 如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者。
  • 无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行)。
  • 如果上层调用者也没有处理的了异常, 就继续向上传递。
  • 一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止。

抛出异常

除了java内置的类会抛出异常时,我们也可以通过throw手动抛出异常。

代码示例:

public static void main(String[] args) {
        System.out.println(divide(10,0));

    }

    private static int divide(int i, int i1) {
        if(i1==0){
            throw new ArithmeticException("分子为0");
        }
        return i/i1;
    }

在这里插入图片描述

Java 异常体系

Java内置了丰富的异常体系,用来表示不同情况下的异常。

下图表示Java内置的异常类之间的继承关系:

在这里插入图片描述

  • 顶层类 Throwable 派生出两个重要的子类, Error 和 Exception。

  • 其中 Error 指的是 Java 运行时内部错误和资源耗尽错误. 应用程序不抛出此类异常. 这种内部错误一旦出现,除了告知用户并使程序终止之外, 再无能无力. 这种情况很少出现。

  • Exception 是我们程序猿所使用的异常类的父类。

  • 其中 Exception 有一个子类称为 RuntimeException , 这里面又派生出很多我们常见的异常类有NullPointerException , IndexOutOfBoundsException 等。

    自定义异常

​ Java 中虽然已经内置了丰富的异常类, 但是我们实际场景中可能还有一些情况需要我们对异常类进行扩

展, 创建符合我们实际情况的异常。

如一下代码,这是一个简单的登录系统。

package T0125;


import java.util.Scanner;

public class TE0125 {

    private static String username="byte";
    private static String password="12345";
    public static void main(String[] args) {
        int count=0;
        Scanner scanner=new Scanner(System.in);

            String u=scanner.next();
            String p=scanner.next();
            try{
                login(u,p);
            }catch (UserError userError){
                userError.printStackTrace();
            }catch (PasswordError passwordError){
                passwordError.printStackTrace();
            }

    }

    public static void login(String username,String password) throws UserError,PasswordError{
        if(!TE0125.username.equals(username)){
            throw new UserError("用户名错误");
        }
        if(!TE0125.password.equals(password)){
            throw new PasswordError("密码错误");
        }
        System.out.println("登陆成功!");
    }
}

以下是自定义的异常类:

package T0125;

class UserError extends Exception {
    public UserError(String message){
        super(message);
    }
}

class PasswordError extends Exception{
    public PasswordError(String message){
        super(message);
    }
}

通过上述的操作就可以自定义异常。

注意事项

  • 自定义异常通常会继承自 Exception 或者 RuntimeException
  • 继承自 Exception 的异常默认是受查异常
  • 继承自 RuntimeException 的异常默认是非受查异常.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值