JAVA语言编程(八):异常

JAVA语言编程(八):异常

  • 1. 异常:
    • 1.1 异常体系:
    • 1.2 异常分类:
    • 1.3 异常的产生过程:
  • 2. 异常的处理:
    • 2.1 throw关键字:
    • 2.2 Objects非空判断:
    • 2.3 异常处理方法1:声明异常throws:
    • 2.4 异常处理方法2:捕获异常:
    • 2.5 throwable类中处理异常的3种方法:
    • 2.6 finally代码块:
    • 2.7 多异常的捕获处理:
    • 2.8 finally的return语句:
    • 2.9 子父类异常:
    • 2.10 自定义异常类:
    • 2.11 自定义异常类的使用:

1. 异常:

在Java等面向对象的语言中,异常本身是一个类,产生异常就是创建并抛出一个异常对象。Java处理异常的方式是中断处理。
异常并不是语法错误。

1.1 异常体系:

Throwable是Java中所有错误和异常的父类。

Throwable体系:
1.Error:严重错误,无法处理的错误,只能事先避免;
2.Exception:异常,可以通过代码纠正。

1.2 异常分类:

Exception:编译期异常
RuntimeException:运行期异常

处理方式:
1.抛给虚拟机处理
2.使用try/catch

package lch;

import java.text.ParseException;
import java.text.SimpleDateFormat;

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

        //编译期异常:
        SimpleDateFormat sdf1 = new SimpleDateFormat();
        try {
     
            sdf1.parse("1999-09-09");
        } catch (ParseException e) {
     
            e.printStackTrace();
        }
        System.out.println("后续代码1");

        //运行期异常:
        int[] arr = {
     1,2,3};
        try {
     
            System.out.println(arr[3]);;
        } catch (Exception e) {
     
            e.printStackTrace();
        }
        System.out.println("后续代码2");

        //错误,必须修改代码
        int[] arr2 = new int[1024*1024*1024];
        System.out.println("后续代码3");

    }
}

1.3 异常的产生过程:

1.根据异常产生的原因创建一个异常对象,这个异常对象包含了异常产生的内容,原因,位置;
2.在发生错误的方法中如果没有try…catch的异常处理逻辑,那么JVM会把异常抛出给方法的调用者main方法来处理这个异常;
3.main方法接收到异常对象,如果main方法也没有异常处理机制,则继续把异常对象抛出给main方法的调用者JVM处理;
4.JVM接收到异常对象,会把异常对象的内容、原因、位置打印在控制台,并终止当前正在运行的Java程序(中断处理)。

package lch;

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

        int a[] = {
     1,2,3,4,5,6};
        System.out.println(getElement(a, 6));

    }

    public static int getElement(int[] a, int index){
     
        return a[index];
    }
}

2. 异常的处理:

2.1 throw关键字:

使用throw关键字在指定的方法中抛出指定的异常。
格式:throw new xxxException("异常产生的原因");

throw关键字必须写在方法内部;
throw后new的关键字必须是Exception或Exception的子类;
throw抛出的异常对象,如果是RuntimeException或其子类,可以不处理,默认交给JVM处理;如果是编译异常,必须自行处理。

package lch;

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

        int a[] = {
     1,2,3,4,5,6};
        System.out.println(getElement(a, 6));
        int a2[] = null;
        System.out.println(getElement(a2, 0));

    }
    
    public static int getElement(int[] a, int index){
     
        if(a==null){
     
            //NullPointerException和ArrayIndexOutOfBoundsException是一个运行期异常,可以不自行处理
            throw new NullPointerException("数组为空!");
        }
        if(index >= a.length){
     
            throw new ArrayIndexOutOfBoundsException("数组越界!");
        }

        return a[index];
    }
}

2.2 Objects非空判断:

Objects是空指针安全的,因为对null值进行了抛出异常操作。

package lch;

import java.util.Objects;

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

        int a[] = null;
        Objects.requireNonNull(a);

    }
}

2.3 异常处理方法1:声明异常throws:

异常处理的第一种方式:交给别人处理。

1.throws必须写在方法声明处。
2.throws声明的对象必须是Exception或其子类。
3.方法内部如果抛出了多个异常,throws必须也声明多个异常。如果抛出的对象有子父类关系,直接声明父类即可。
4.调用了一个声明抛出异常的方法,就必须处理声明的异常。要么继续使用throws抛出,要么try…catch。

package lch;

import java.io.FileNotFoundException;
import java.io.IOException;

public class fangfa {
     
    public static void main(String[] args) throws IOException{
     

        judge("C:\\a.txt");

    }

    public static void judge(String str) throws IOException{
     
        if(!str.endsWith(".txt")){
     
            throw new IOException();
        }
        if(!str.equals("C:\\a.txt")){
     
            throw new FileNotFoundException();
        }
    }
}

2.4 异常处理方法2:捕获异常:

格式:try{可能异常的代码}catch(定义一个异常变量,用来接收抛出的异常){异常的处理逻辑}

1.可以使用多个catch;
2.如果try中产生了异常,那么就会执行catch中的处理逻辑,然后继续执行try…catch之后的代码。

package lch;

import java.io.FileNotFoundException;
import java.io.IOException;

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

        try{
     
            judge("qsw");
            System.out.println("后续代码1");
        }catch(FileNotFoundException e){
     
            System.out.println("后缀错误");
        }catch(IOException e){
     
            System.out.println("名称错误");
        }

        System.out.println("后续代码2");

    }

    public static void judge(String str) throws IOException{
     
        if(!str.endsWith(".txt")){
     
            throw new IOException();
        }
        if(!str.equals("C:\\a.txt")){
     
            throw new FileNotFoundException();
        }
    }
}

2.5 throwable类中处理异常的3种方法:

package lch;

import java.io.FileNotFoundException;
import java.io.IOException;

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

        try{
     
            judge("qsw");
            System.out.println("后续代码1");
        }catch(IOException e){
     
            System.out.println(e);
            System.out.println(e.toString());
            e.printStackTrace();
        }

        System.out.println("后续代码2");

    }

    public static void judge(String str) throws IOException{
     
        if(!str.endsWith(".txt")){
     
            throw new IOException();
        }
        if(!str.equals("C:\\a.txt")){
     
            throw new FileNotFoundException();
        }
    }
}

2.6 finally代码块:

finally必须和try一起使用,修饰的代码无论程序是否出现异常,都会执行。
finally一般用于资源释放,因为无论程序是否出现异常,我们都需要释放资源。

package lch;

import java.io.FileNotFoundException;
import java.io.IOException;

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

        try{
     
            judge("qsw");
            System.out.println("后续代码1");
        }catch(IOException e){
     
            e.printStackTrace();
        }finally{
     
            System.out.println("无论是否出现异常,都需要执行的代码");
        }

        System.out.println("后续代码2");

    }

    public static void judge(String str) throws IOException{
     
        if(!str.endsWith(".txt")){
     
            throw new IOException();
        }
        if(!str.equals("C:\\a.txt")){
     
            throw new FileNotFoundException();
        }
    }
}

2.7 多异常的捕获处理:

多个catch定义的异常变量,如果有子父类关系,子类必须写在前面,否则就会报错。

多个异常一次捕获多次处理:

package lch;

import java.util.List;

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

        int a[] = {
     1,3,5};
        List<Integer> list1 = List.of(1,3,5);

        try{
     
            System.out.println(a[3]);
            System.out.println(list1.get(3));
        }catch(ArrayIndexOutOfBoundsException e1){
     
            e1.printStackTrace();
        }catch(IndexOutOfBoundsException e2){
     
            e2.printStackTrace();
        }

    }

}

多个异常一次捕获一次处理:

package lch;

import java.util.List;

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

        int a[] = {
     1,3,5};
        List<Integer> list1 = List.of(1,3,5);

        try{
     
            System.out.println(a[3]);
            System.out.println(list1.get(3));
        }catch(IndexOutOfBoundsException e2){
     
            e2.printStackTrace();
        }

    }
}

2.8 finally的return语句:

如果finally中有return语句,永远返回finally中的结果。(需要避免这种情况)

package lch;

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

        System.out.println(method1());

    }

    public static int method1(){
     
        int a = 10;
        try{
     
            return a;
        }catch(Exception e){
     
            e.printStackTrace();
        }finally{
     
            return 20;
        }
    }
}

2.9 子父类异常:

如果父类抛出多个异常,子类重写父类方法时,抛出和父类相同的异常或父类异常的子类或不抛出异常。
如果父类没有抛出异常,子类重写父类方法时也不可抛出异常,此时子类产生该异常,只能捕获处理,不能声明抛出。

2.10 自定义异常类:

自定义异常类继承Exception,那么自定义异常类就是一个编译器异常。
继承RuntimeException,那么自定义异常类就是一个运行期异常。

package lch;

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

2.11 自定义异常类的使用:

package lch;

import java.util.Scanner;

public class fangfa {
     
    public static void main(String[] args) throws RegisterException{
     

        String[] name = {
     "alex", "bob", "cindy"};
        System.out.println("请输入要注册的用户名:");
        Scanner sc = new Scanner(System.in);
        String username = sc.next();

        check(name, username);

    }

    public static void check(String[] name, String username) throws RegisterException{
     
        for(String str : name){
     
            if(str.equals(username)){
     
                throw new RegisterException("该用户名已被注册!");
            }
        }
    }
}

你可能感兴趣的:(Java基础)