异常--总结

防御式编程:有LBYL和EAFP两种
LBYL:在操作前就做好充分检查。
EAFP:先进行操作,遇到问题的时候再处理。
而异常核心思想为EAFP。

异常:程序在运行时出现错误时通知调用者的一种机制。异常的种类有很多,不同种类的异常有不同的含义,也有其对应的处理方式。

捕获异常:

try{        
	有可能出现异常的语句 ; 
}[catch (异常类型 异常对象) { 
} ... ] 
[finally {   
	异常的出口
}]

上述为异常的基本语法,其中try代码块中放的是可能出现异常的代码,catch代码块中放的是出现异常后的处理行为,finally代码块中的代码用于善后工作,会在最后执行。

根据下面代码看一下:

public static void main1(String[] args) {
    int[] arr = {1,2,3};
    try{
        System.out.println("before");
        System.out.println(arr[100]);
        System.out.println("after");
    } catch (ArrayIndexOutOfBoundsException e) {
        //打印出现异常的调用栈
        e.printStackTrace();
    }
    System.out.println("after try catch");
}

执行结果如下:
在这里插入图片描述
我们发现,一旦try中出现异常,try代码块中的程序就不会被继续执行,而是交给catch执行,catch执行完之后会继续往下执行的。

关于异常的处理方式:
1.对于比较严重的事情,应该让程序直接崩溃,防止会造成更严重的后果。
2.对于不太严重的事情,可以记录错误日志,并通过监控报警程序及时通知调用者。
3.对于可能会恢复的问题,可以尝试进行重试。

catch只能处理对应种类的异常:

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 (ArrayIndexOutOfBoundsException e) {
        //打印出现异常的调用栈
        e.printStackTrace();
    }
    System.out.println("after try catch");
}

在这里插入图片描述
对于上面的代码来说,catch只处理了数组越界异常,无法捕获到空指针异常,因为异常类型不匹配。

finally表示最后的善后工作,比如释放资源:

public static void main2(String[] args) {
    int[] arr = {1,2,3};
    try {
        System.out.println("before");
        arr = null;
        System.out.println(arr[100]);
        System.out.println("after");
    } catch (ArrayIndexOutOfBoundsException | NullPointerException e) {
        //System.out.println("下标越界异常");
        e.printStackTrace();
    } finally {
        System.out.println("finally code");
    }
}

执行结果(无论是否存在异常,finally中的代码都一定会被执行):
在这里插入图片描述
finally 执行的时机是在方法返回之前,如果 finally 中也存在 return
语句, 那么就会执行最后finally 中的 return, 从而不会执行到 try 中原有的 return.

public static void main(String[] args) {     
	System.out.println(func()); 
} 
public static int func() {     
	try {         
		return 10;     
	} finally {         
		return 20;     
	} 
} 

如果本方法中没有合适的处理异常的方法,就会沿着调用栈向上传递,而如果向上一直传递都没有合适的方法处理异常,最终会交给JVM处理,程序就会放生异常终止,与未使用try catch一样。

异常的处理流程

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

抛出异常:(throw关键字)
Java中除了会有一些内置的异常,也可以手动的抛出一个异常。

public static void main(String[] args){
    System.out.println(divide(10,0));
}
public static int divide(int x,int y) throws ArithmeticException {
    if (y == 0) {
        throw new ArithmeticException("除0异常");
    }
    return x / y;
}

在这里插入图片描述
显示处理

1.使用try catch包裹起来

public static  String readFile1() {
    File file = new File("d:/test.txt");
    Scanner sc = null;
    try {
        sc = new Scanner(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    return sc.nextLine();
 }
 public static void main(String[] args){
    System.out.println(readFile());
 }

2.在方法上加上异常说明,相当于将处理动作交给上级调用者。

public static void main(String[] args){
    try {
        System.out.println(readFile());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}
public static String readFile() throws FileNotFoundException {
    File file = new File("d:/test.txt");
    Scanner sc = new Scanner(file);
    return sc.nextLine();
}

最后自定义一个异常类,模仿用户登录系统。

class UserError extends Exception {
    public UserError (String message) {
        super(message);
    }
}
class PasswordError extends Exception {
    public PasswordError (String message) {
        super(message);
    }
}
public class Test1 {
    private static String userName = "admin";
    private static String password = "123456";
    public static void main(String[] args) {
        try {
            login("admin","123456");
        } catch (PasswordError | UserError passwordError) {
            passwordError.printStackTrace();
        }
    }
    public static void login(String userName,String password) throws 
     								UserError, PasswordError {
        if (! Test1.userName.equals(userName)) {
            //处理用户名错误
            throw new UserError("用户名错误");
        }
        if (! Test1.password.equals(password))  {
            //处理密码错误
            throw new PasswordError("密码错误");
        }
        System.out.println("登录成功");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值