【JAVASE】带你一文了解java中异常捕获

引言

    我们在java的学习之中可能会听到异常这个词,那么当程序出现异常之后,后面的程序还能正常运行吗,我们又该如何处理异常呢,本文就带你详细了解java中的异常。

异常的概念:

      在生活中,我们时常会感觉到不舒服,头疼,程序中也是一样的,程序员们每天可能会书写大量的代码,有时代码难免会有些问题,比如:数据格式不对,或者数据运算有问题。在java中,将程序在执行过程中不正常的行为,统称为异常。

这里给大家举几个例子:

算术运算异常:

        System.out.println(100/0);

比如这行代码,显然0不能作为除数,所以运行时会发生异常。

数组越界异常:

 int[] arr=new int[10];
        System.out.println(arr[10]);

异常的分类:

我们发现,在程序出现不同的问题的时候,报的异常信息也是不一样的,这是因为异常中是分很多种类的,面对不同的异常,会打印不同的信息。比如我们刚才看到的:数组越界异常,算数运算异常。

      这里的Throwable是异常大类体系中的顶层,由次派生出Error和Expecption两种子类,

Error:这种属于比较严重的问题,一旦出现这种问题,我们一般说程序运行时出现了错误。(比如栈溢出)。

Expecption:这种异常,程序员直接对代码进形一定的修改,就可以使程序继续运行了,我们平时所说的异常一般指的就是Expecption。

我们可以按照异常发生的时间的不同可以分为:

  1. 编译时异常

即在程序编写的时候就发生的异常,有时也称为受检查异常(ps:其实受的就是编译器的检查

class Person{
    String name;
    int age;

    @Override
    public  Person clone()  {
        return (Person)super.clone();
    }
}

2.运行时异常:

在程序运行时发生的异常,称为运行时异常,也称为(非受查异常)比如NULLPointerException,以及我们刚开始就讲到的算数运算异常。

如何处理异常:

防御型编程(LBYL):

LBYL:即在程序运行之前就做了充分的检查,即事前防御。

boolean ret = false;
ret = 登陆游戏();
if (!ret) {
处理登陆游戏错误;
return;
}
ret = 开始匹配();
if (!ret) {
处理匹配错误;
return;
}
ret = 游戏确认();
if (!ret) {
处理游戏确认错误;
return;
}
ret = 选择英雄();
if (!ret) {
处理选择英雄错误;
return;

这样的代码, 将和正常代码混在了一起,比较混乱,代码的可读性变差。

时候认错型(EAFP):

这里的意思是先写代码,等到遇到问题了在处理(这是常用的处理异常方法)。给大家举个例子帮助理解:

try {
登陆游戏();
开始匹配();
游戏确认();
选择英雄();
载入游戏画面();
...
} catch (登陆游戏异常) {
处理登陆游戏异常;
} catch (开始匹配异常) {
处理开始匹配异常;
} catch (游戏确认异常) {
处理游戏确认异常;
} catch (选择英雄异常) {
处理选择英雄异常;
} catch (载入游戏画面异常) {
处理载入游戏画面异常;
}

这是一段伪代码哦!!!!异常

在处理异常的时候,我们将经常会用到5个关键字:throw,try,catch,final,throws 

异常的抛出:

当程序出现异常的时候,我们需要将异常的情况报告给调用者,我们可以使用Java中的提供的throw关键字,抛出一个指定的异常对象,将错误的信息告知给调用者。

public static int getElement(int[] array,int index){
     if(arrar==null){
           throw new NUllPointException("形参为空");
     }
}

【注意事项】

1. throw
必须写在方法体内部
2.
抛出的对象必须是
Exception
或者
Exception
的子类对象
3.
如果抛出的是
RunTimeException
或者
RunTimeException
的子类,则可以不用处理,直接交给
JVM
来处理
4.
如果抛出的是编译时异常,用户必须处理,否则无法通过编译
5.
异常一旦抛出,其后的代码就不会执行

 异常的捕获:

     异常的捕获,即异常的处理方式,主要分为两种:throws,和try-catch捕获处理。

throw即对异常做了一个声明,告诉程序我知道这里有一个异常,但是并没有具体将异常处理,而try-catch则是将可能出错的代码放到中,在catch()匹配捕获的异常然后在方法体里面对异常进行处理,下面会有例子帮助你理解的~~

这里先是举一个throw的例子:

 public static void func(int[] array) throws Exception {
        if(array == null) {
            throw new Exception("传个参数看看..."+array);
        }
    }
//并没有处理异常

try-catch

public static void main3(String[] args) {
        try {
            int[] array = null;
            System.out.println(array.length);
            //System.out.println("hahaha......");
        }catch (ArithmeticException e) {
            e.printStackTrace();
            System.out.println("处理ArithmeticException异常....");
        }catch (NullPointerException e) {
            e.printStackTrace();
            System.out.println("处理NullPointerException异常....");
        }
        System.out.println("程序继续执行.....");
    }

这里是发生的空指针异常,所以应该是第二个catch捕捉成功。

需要注意:try如果有多个异常,只会捕获第一个异常哦!!!

finally关键字:

       在编写java程序的时候,无论程序是否发生异常,我们都要执行一些特定的代码,比如,当你浏览的网页出错时,应该输出提示信息。而finally关键字就是来解决这种问题的。下面还是一代吗的形式给大家演示一下。

语法格式:
try{
// 可能会发生异常的代码
}catch(异常类型 e){
// 对捕获到的异常进行处理
}finally{
// 此处的语句无论是否发生异常,都会被执行到
}
// 如果没有抛出异常,或者异常被捕获处理了,这里的代码也会执行

举个例子:

public static void main(String[] args) {
try{
int[] arr = {1,2,3};
arr[100] = 10;
arr[0] = 10;
}catch (ArrayIndexOutOfBoundsException e){
System.out.println(e);
}finally {
System.out.println("finally中的代码一定会执行");
}
System.out.println("如果没有抛出异常,或者异常被处理了,try-catch后的代码也会执行");
}

我们知道了finally一般是在异常发生之后执行的,这里需要特别说明:finally中的代码一定会执行,并且由于它的位置在异常之后,常常在程序的结尾,处理一些善后工作。并且,在try-catch中如果有return他会先执行后面的finally中的语句,后return,如果你的finally中有return那么会优先执行finally中的return,而不执行try-catch中的return!!!


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

 

自定义异常类:

在我们写代码的时候。有时想要对可能出现问题的代码进行捕获,但是往往有的异常编译器并没有给我们提供,此时我们就需要自己定义异常类去完成异常的报错。

比如这里,我们实现一个简单的用户个人信息的登录系统:

class UserNameException extends Exception {
public UserNameException(String message) {
super(message);
}
}
class PasswordException extends Exception {
public PasswordException(String message) {
super(message);
}
}
public class LogIn {
private String userName = "admin";
private String password = "123456";
public static void loginInfo(String userName, String password)
throws UserNameException,PasswordException{
if (!userName.equals(userName)) {
throw new UserNameException("用户名错误!");
}
if (!password.equals(password)) {
throw new PasswordException("用户名错误!");
}
System.out.println("登陆成功");
}
public static void main(String[] args) {
try {
loginInfo("admin", "123456");
} catch (UserNameException e) {
e.printStackTrace();
} catch (PasswordException e) {
e.printStackTrace();//这个是可以显示你出现异常具体的地方
}
}
}
注意事项
  • 自定义异常通常会继承自 Exception 或者 RuntimeException
  • 继承自 Exception 的异常默认是受查异常
  • 继承自 RuntimeException 的异常默认是非受查异常

好了,今天就分享到这里了,喜欢就一键三连,我们下次再见~~

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>