JavaSE基础(28) Java 异常

概念

1. 什么是异常:异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序。

2. 什么是异常处理:异常处理是编程语言的一种机制,对可能出现的问题进行预处理,异常处理完毕后,程序可以继续运行,增强系统的健壮性和安全性。

3. 异常处理的必要性:异常处理用于解决一些程序无法掌控,但又必须面对的情况。为了程序能继续运行,就需要把这些情况进行异常处理。异常处理的方法通常有以下几种:

        1) 将异常通知给开发人员、运维人员或用户

        2) 因为异常中断的程序以适当的方式继续运行,或者退出

        3) 保存用户的当前操作,或者进行数据回滚

        4) 释放资源

4. Java 编程语言提供了异常处理机制为程序提供了错误处理的能力

JavaSE基础(28) Java 异常_第1张图片

 异常分类

1) Throwable 类是 Java 异常类型的顶层父类,一个对象只有是 Throwable类的实例,才是一个异常对象,才能被异常处理机制识别,位于java.lang包中。

2) 按照错误严重性,从 Throwale 类中衍生出 Error 和 Exception 两大派系

        a) Error(错误):程序在执行过程中所遇到的硬件或系统的错误。错误对程序而言是致命的,将导致程序无法运行。不允许捕获。当发生 Error 时,只能依靠外界干预。常见错误: StackOverflowError、OutOfMemoryError等。

        b) Exception(异常):是程序运行过程中,可以预料的意外情况。比如空指针,数组下标越界。异常出现可以被捕获处理掉,使程序继续运行。

public class Demo {
    public static void main(String[] args) {
        //异常:可以处理
//        int[] arr = {3,2,4,5};
//        System.out.println("arr[4]:"+arr[4]);//java.lang.ArrayIndexOutOfBoundsException: 4

        //错误:不能处理
        //int[] arr2 = new int[1024*1024*1024];//java.lang.OutOfMemoryError: Java heap space


        //异常:检查异常和运行时异常
        int div = 10/0;//java.lang.ArithmeticException: / by zero//编译器不检查的异常

        //编译器能检查出来:检查异常
        //FileInputStream fis = new FileInputStream("d:\\hello.txt");
        
    }
}

3) Exception:又分为编译时异常和运行时异常。

        RuntimeException:运行时异常,可处理,可不处理。

        CheckedException:检查时异常,必须处理

        a) 运行时异常都是 RuntimeException 类及其子类, 这些异常是不检查的异常, 是在程序运行的时候可能会发生的, 所以程序可以捕捉, 也可以不捕捉。程序应该从逻辑角度去尽量避免。如:空指针、数组下标越界等

        NullPointerException

        ArrayIndexOutOfBoundsException//数组越界

        ArithemicException

        ClassCastException

        NumberFormatException

        b) 编译时异常也叫检查异常,是运行时异常以外的异常, 也是 Exception 及其子类, 这些异常从程序的角度来说是必须经过捕捉检查处理的, 否则不能通过编译. 如 IOException、SQLException 等。

        FileNotFoundExcetpion

        IOException        

        SQLException

import java.io.FileInputStream;

public class ExceptionDemo {
    public static void main(String[] args) {

        //异常:检查异常和运行时异常
        try {
            int div = 10 / 0;//java.lang.ArithmeticException: / by zero//编译器不检查的异常
            FileInputStream fis = new FileInputStream("d:\\hello.txt");
            System.out.println("----------------------");
        }
//        catch(ArithmeticException e){
//            System.out.println("捕获了异常....");
//        }

//        catch (FileNotFoundException e) {
//            e.printStackTrace();
//        }
        catch (Exception e) {
            e.printStackTrace();//追踪信息
        } finally {//可选的,可以有,可以没有
            //无论是否产生异常,都会执行finally语句块里面的代码
            System.out.println("finally语句块一定要执行....");
        }


        System.out.println("hello,world!!!");
        System.out.println("hello,world!!!");
        System.out.println("hello,world!!!");

        //编译器能检查出来:检查异常
        //FileInputStream fis = new FileInputStream("d:\\hello.txt");
    }
}

4) 异常分类的结构图

JavaSE基础(28) Java 异常_第2张图片

异常产生和传递

异常产生

        自动抛出异常:当程序在运行时遇到不符合规范的代码或结果时,会产生异常。

        手动抛出异常:语法:throw new 异常类型(“实际参数”)。

        产生异常结果:相当于遇到 return语句,导致程序因异常而终止。

异常传递

        按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)。

        受查异常:throws 声明异常,修饰在方法参数列表后端。

        运行时异常:因可处理可不处理,无需声明异常。

异常的处理

捕获异常:try,catch,finally

语法规则:

try{
    //可能产生异常的代码
}catch(异常类型1 e){
    //捕获异常的处理
}catch(异常类型2 e){
    //捕获异常的处理
}finally{
    //无论程序是否产生异常,此处的代码一定会被执行。
    //比如说:释放资源,删除临时文件等。。。
}

 

注意点:

        1.一个try可以匹配多个catch语句

        2.如果try中产生了异常对象,那么会跳出try,进到相应的catch中处理异常,从上向下匹配。

        3.如果是多个catch语句,那么小的异常捕获处理写前面,大的异常捕获处理写后面。

        4.finally是可选的

声明异常 throws

方法级别上,向外抛出异常。

方法的声明上就要通过throws关键字声明抛出异常:

public static void test1(int i,int j)throws NullPointerException{

}
[修饰符1,修饰符2.。。] 返回值类型/void 方法名(参数列表) 异常的声明{

}

按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)。

public static void test1() throws ArithmeticException{
    int i=10;
    int j =0;
    int div = i/j;
    System.out.println("div:"+div);
    System.out.println("test1.....end.....");
}

public static void test2() throws ArithmeticException{
    // try {
    //     test1();
    // } catch (ArithmeticException e) {
    //     e.printStackTrace();
    // }
    test1();
    System.out.println("test2......end....");
}

public static void test3() throws FileNotFoundException {
    File file = new File("c:\\a.jpg");
    FileInputStream fis = new FileInputStream(file);
}

public static void test4() throws Exception{
    //FileNotFoundException
    test3();//检查异常一定要处理,强制处理
}

public static void test5() throws Exception{

}
public static void test6(){
    test5();
}

public static void main(String[] args) {
    try {
        test2();
    } catch (ArithmeticException e) {
        e.printStackTrace();
    }
    System.out.println("main......end......");
}

运行时异常的抛出,不一定要处理

检查异常的抛出,必须处理

Exception和RuntimeException的区别?

1.RuntimeException是Exception的子类。

2.Exception包含了受检异常,所以抛出Exception以及受检异常时,代码中一定要给与处理。如果抛出的是RuntimeException(运行时异常,非受检)以及它的子类异常,程序中不一定非要处理。

3.重写的时候,子类不能抛出比父类更大的异常

class Person{
    public void eat() throws FileNotFoundException{
    
    }
}

class Student extends Person{
    @Override
    public void eat() throws Exception{
    
    }
}

public class Demo7 {
    public void test(Person p){
        p.eat();
    }
    public static void main(String[] args) {
    }
}

throw 关键字

throw和throws的区别?

1.throws,用于定义方法的时候,声明该方法向外抛出异常。

2.throw,主动抛出一个异常的对象。打断程序的执行。配合trycatch,或者throws来使用。

Exception exception = new Exception("我自定义的异常。。");

try {
    throw exception;//自己主动抛出的异常
} catch (Exception e) {
    e.printStackTrace();
}

System.out.println("main......end.....");

自定义异常

1) 上面的异常体系结构图都是系统自带的,系统自己处理,但是很多时候项目会出现特有问题,而这些问题并未被 Java 所描述并封装成对象,所以对于这些特有的问题可以按照封装的思想,将特有的问题进行自定义异常封装。要想创建自定义异常,需要继承 Throwable 或者他的子类 Exception。

2) 使用自定义异常类的步骤

JavaSE基础(28) Java 异常_第3张图片

 异常类型名称望文生义,可在发生特定问题时抛出对应的异常。

常用构造方法:

无参数构造方法。

String message参数的构造方法。

public class AgeException  extends RuntimeException{
    
    public AgeException(String message) {
        super(message);
        // TODO Auto-generated constructor stub
    }

    public AgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace){
        super(message, cause, enableSuppression, writableStackTrace);
    }
    
    public AgeException(String message, Throwable cause) {
        super(message, cause);
        // TODO Auto-generated constructor stub
    }
    
    public AgeException(Throwable cause) {
        super(cause);
        // TODO Auto-generated constructor stub
    }
    
}

你可能感兴趣的:(JavaSE基础,java)