java中的异常处理以及自定义异常

一、异常的概念以及产生的原因及分类

1.异常的概念

异常就是一个在程序执行期间发生的事件,它中断了正在执行程序的正常指令流。为了能够显示这个异常并且处理异常,这个时候我们就需要通过异常类来进行处理。

(通俗来讲就是运行的程序突然被中断了,这就是异常)

2.异常产生的原因

(1)自身写代码的问题。比如数组越界异常、空指针异常、算数异常等等。这些异常都是因为我们自身写代码时出的错误,所以这些错误往往是在程序代码中进行修改;

(2)java自身内部出现的错误。比如java虚拟机出现了错误;

(3)自身手动产生的异常。因为有时候有些代码段可能会出现错误,所以我们就会通过throw手动来抛出异常信息,当这个代码段真的出现错误时,我们就可以通过这个异常定位到这个代码段;

3.异常的分类

(1)Throwable:它是异常类的顶层类,它下面有两个重要的子类:Error、Exception

Error用来表示错误、Exception用来表示异常;

(2)Exception:用于程序可能出现异常的类。它可以用来自定义异常(即自己定制异常信息)

(3)Error:用于显示运行时与系统本身有关的错误

运行时异常都是 RuntimeException 类及其子类异常,它继承于Exception。这些异常一般由程序逻辑错误引起,程序应该从逻辑角度尽可能避免这类异常的发生。

比如10/0会出现异常:

 编译时异常:除了运行时异常的之外的异常,类型上都属于Exception及其子类,这类异常是必须处理的异常,在程序还没有运行的时候就要进行处理的异常,如果不处理的话,编译就不能通过。

二、异常的处理

1.通过throw进行异常抛出

在编写程序的时候,如果程序出现错误,这个时候就需要将程序的错误信息发送给调用者,这个时候可以通过throw抛出异常,在程序运行时出现错误,调用者可以根据这个抛出的错误快速定位到错误处,进行检查解决错误;

如:

通过抛出的错误信息,可以快速的定位到出错的为14行,这个时候可以定位到14行进行检查解决。

2.通过throws进行异常声明 

java中的异常处理以及自定义异常_第1张图片

 throws在方法参数之后声明。当程序中出现编译时异常时,自己不想处理这个异常,但是不处理这个异常又不能运行程序,这个时候就可以通过throws将异常交给方法的调用者来处理。

细节:当声明异常时,如果有多个异常用逗号进行分隔;

            如果多个异常有父子关系,这个时候直接写父类异常就行了(因为父类异常里面包含了子类异常,子类异常不过是对父类异常中的异常进行了细化);

            调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出

3.通过try-catch进行异常捕获并处理

        如果程序抛出了异常,那么可以通过try来捕获它里面代码出现的异常,catch再打印异常信息

三、异常的传递

1.异常传递

在方法实现中出现的异常,如果在实现中没有处理,那么会往调用处传递

换句话说,可以在方法实现处或方法调用处进行异常处理(捕获)

运行时异常

(1)调用处传递、实现处传递

案例

public static void main(String[] args) {    
    //异常传递:在方法实现中出现异常;可传递到调用处
    //异常传递可在实现处或调用处处理
    //案例:运行时异常传递
    //1.方法实现处捕获---方法实现处后面也能执行
    //2.方法调用处捕获---main方法后面可以执行
    try {
        a();
    } catch (Exception e) {
        e.printStackTrace();
    }

    System.out.println("最后执行...");
}

private static void a() {
    //try {
    int i=1/0;
    //}catch (Exception e) {
    //    e.printStackTrace();
    //}
    System.out.println("方法实现的最后执行..");
}

(2)编译时异常传递

案例:

public static void main(String[] args) {
    //异常传递:在方法实现中出现异常;可传递到调用处
    //异常传递可在实现处或调用处处理
    //案例:运行时异常传递
    //1.方法实现处捕获---方法实现处后面也能执行
    //2.方法调用处捕获---main方法后面可以执行
    try {
        a();
    } catch (Exception e) {
        e.printStackTrace();
    }

    System.out.println("最后执行...");
}
private static void a() {
    //try {
    int i=1/0;
    //}catch (Exception e) {
    //    e.printStackTrace();
    //}
    System.out.println("方法实现的最后执行..");
}

2.finnally

finally主要用在捕获中,表示无论是否捕获住,都会执行改区域的代码

无论程序是否崩溃,都会执行finally里的代码

用处:常用于关闭资源io、数据库等

try{

}catch(Exception e){

}finally{

}

try{

}finally{

}

3.finnally与return优先级的比较

结论:finally优先级更高,return之前,必须先执行finally

案例:

try {
    int i = 1/0;
}catch (Exception e) {
    System.out.println("捕获异常..");
    return;
}finally {
    System.out.println("最后..");
}

System.out.println("main最后");

四、自定义异常

在项目中,如果我们需要自己定制一个异常的提示,那么我们需要自己来设计;例如ID为空的异常,通过自定义异常我们能够更明确出现的是什么问题

案例:

自定义异常类继承运行时异常类

当不符合条件的时候,抛出异常

在方法调用处try捕获异常,catch打印异常信息

注意:

自定义异常默认会继承 Exception 或者 RuntimeException

继承于 Exception 的异常默认是受查异常

继承于 RuntimeException 的异常默认是非受查异常

class StuAttrException extends RuntimeException{
    public StuAttrException(String msg) {
        super(msg);
    }
}

//自定义异常案例:创建学生对象,属性需要进行封装,
//并判断姓名长度不能大于6;年龄必须在1~100之间
//自定义异常好处:可读性更好

class Student{
    private String name;
    private int    age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        if(name.length()>6) {
            //System.out.println("姓名出现异常...重新录入");
            //抛出单个对象--手动产生异常
            throw new StuAttrException("姓名出现异常...重新录入");
        }else {
            this.name = name;
        }
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        if(age>100||age<=0) {
            //System.out.println("年龄出现异常...重新录入");

        
            throw new StuAttrException("年龄出现异常...重新录入");
        }else {
            this.age = age;
        }
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
}
public class Test1 {
    public static void main(String[] args) {
        Student st = new Student();
        try {
            st.setName("张三丰凤飞飞纷纷");
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            st.setAge(120);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("执行最后...");
    }
}

五、了解重写中的异常

重写中的异常:不能抛出比父类更宽泛的异常

class Animal{
    public void eat() throws RuntimeException {
        
    }
}
class Dog extends Animal{
    @Override
    public void eat() throws RuntimeException { //此处子类不能抛Exception异常
    }
}

各位客官请听下回分解

创作不易,如果觉得还不错的话,可以点个赞给我个鼓励嘛

你可能感兴趣的:(Java基础,java,开发语言)