Java中的异常捕获

 

目录

 1.代码中的常见异常

1.1算术异常

1.2数组越界异常

1.3空指针异常

 1.4输入类型异常

2.异常的基本用法

2.1 捕获异常

 2.2 多个异常的捕捉

 2.4finally的注意事项

2.5 抛出异常

 3.自定义异常类

3.1用户登录


 1.代码中的常见异常

异常就是程序在运行时出现错误时通知调用者的一种机制

1.1算术异常

常见的算术异常就是指分母为零的情况

public class Abnormal {
    public static void main(String[] args) {
        System.out.println(5/0);
    }
}

编译结果

Java中的异常捕获_第1张图片

1.2数组越界异常

public class Abnormal {
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        System.out.println(array[10]);
    }
}

 我定义的数组下标最长为4,但是要访问下标为10的数字明显已经超出了,所以执行结果会显示越界

执行结果 Java中的异常捕获_第2张图片

1.3空指针异常

public class Abnormal {
    public static void main(String[] args) {
        String str = null;
        System.out.println(str.length());
       
    }
}

 执行结果

 Java中的异常捕获_第3张图片

 1.4输入类型异常

import java.util.Scanner;

public class Abnormal {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        System.out.println(n);
        
    }
}

我定义的是一个整型的数字,但是我输入的是字符串类型,所以会执行出错

 Java中的异常捕获_第4张图片

2.异常的基本用法

2.1 捕获异常

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

基本语法

try {

      有可能出现异常的语句;

}catch (异常类型 异常对象){

}

finally {

          异常出口

}

 举个算术异常的例子

public class Abnormal {
    public static void main(String[] args) {
        try {
            System.out.println(10/0);
        }catch (ArithmeticException e) {
            e.printStackTrace();//找到异常出现的位置
            System.out.println("捕捉到了算术异常");
        }
        System.out.println(555);
    }
}

从执行结果来看,捕捉了异常之后并不会影响后面的代码运行

  Java中的异常捕获_第5张图片

 我们来看下如果不捕获异常的话,后面的代码会不会继续执行


public class Abnormal {
    public static void main(String[] args) {
        System.out.println(10/0);
        System.out.println(55);
    }
}

由执行结果可知,异常后面的代码不会继续执行

Java中的异常捕获_第6张图片

 2.2 多个异常的捕捉

结构(就是可以有多个catch)

在catch多个时,最好是先子类后父类

try {

} catch(Exception e ) {

e.printStackTrace ( );

}catch(Exception e ) {

e.printStackTrace ( );

}

在程序中,我们可以写多个代码捕捉,但如果同时出现多个代码错误时,一次只能捕捉一次,从最开始定义的开始,解决完第一个才能捕捉下一个,如下所示

我们先举例一个空指针异常和数组越界异常的例子

首先会捕捉空指针,空指针解决后才会捕捉数组越界

public class Abnormal {
    public static void main(String[] args) {
        String str = null;
        int[] array = {1,2,3};
        try {
            System.out.println(str.length());
            System.out.println(array[5]);
        }catch (NullPointerException e) {
            e.printStackTrace();
            System.out.println("捕获空指针异常");
        }catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
            System.out.println("捕获数组越界异常");
        }
    }
}

看执行结果可知,一次只抛出一个

 Java中的异常捕获_第7张图片

 2.3异常的父类

Exception 类是所有异常类的父类,因此可以用这个类型表示捕捉所有异常。

但父类捕捉到的异常不会告诉你是有什么异常,这个需要自己看。

public class Abnormal {
    public static void main(String[] args) {
        String str = null;
        try {
            System.out.println(str.length());
        }catch (Exception e) {
            e.printStackTrace();
            System.out.println("有异常");
        }
    }
}

  Java中的异常捕获_第8张图片

 2.4finally的注意事项

import java.util.Scanner;

public class Abnormal {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        try {
            System.out.println(10/n);
        }catch (Exception e) {
            e.printStackTrace();
            System.out.println("捕获输入有误");
        }finally {
            System.out.println("finally执行了");

        }
    }

 在程序中,无论有没有捕获异常,finally都会执行

没有异常时:

 Java中的异常捕获_第9张图片

 有异常时:

 Java中的异常捕获_第10张图片

 finally 会有一个弊端,会覆盖前面不会出错的返回值,所以不建议在finally 中写return

public class Abnormal {
    public static int func() {
        int a = 12;
        try {
            return a;
        }catch (ArithmeticException e) {
            e.printStackTrace();
        }finally {
            return 20;
        }
    }
    public static void main(String[] args) {
        System.out.println(func());

    }

按原理返回的是12,但由于finally 执行了,所以返回了20;

 Java中的异常捕获_第11张图片

2.5 抛出异常

除了 Java 内置的类会抛出一些异常之外 , 也可以手动抛出某个异常 . 使用 throw 关键字完成这个操作 .
当 x 不为零时,就不会抛出异常
public class Abnormal {
    public static void func1(int x) throws ArithmeticException {
        if(x == 0) {
            throw new ArithmeticException("/ by zero");
        }
    }

    public static void main(String[] args) {
        try {
            func1(1);
        }catch (ArithmeticException e) {
            e.printStackTrace();
        }
    }
}

  Java中的异常捕获_第12张图片

    当 x 为0时,就会抛出异常

public class Abnormal {
    public static void func1(int x) throws ArithmeticException {
        if(x == 0) {
            throw new ArithmeticException("/ by zero");
        }
    }

    public static void main(String[] args) {
        try {
            func1(1);
        }catch (ArithmeticException e) {
            e.printStackTrace();
        }
    }
}

  Java中的异常捕获_第13张图片

 3.自定义异常类

自定义异常类就是字面上的意思,用于我们实现一些功能的测试时候抛出的一些异常,且这些异常都是我们觉得有bug的地方。

3.1用户登录

自定义异常通常会继承自 Exception 或者 RuntimeException
继承自 Exception 的异常默认是受查异常
继承自 RuntimeException Exception 的异常默认是非受查异常

我们实现一个简单的登录功能,可以抛出两个异常,一个用户名错误,另一个是密码错误。


/**
 * 自定义非受查异常类
 */
class NameException extends RuntimeException{
    public NameException(String message) {
        super(message);
    }
}
class PasswordException extends RuntimeException{
    public PasswordException(String message) {
        super(message);
    }
}

public class LogOn {
    private static final String name = "fly";
    private static final String password = "123456";

    /**
     * 定义抛出异常
     * @param name
     * @param password
     * @throws NameException
     * @throws PasswordException
     */
    public static void logon(String name,String password) throws NameException,PasswordException{
        if (!LogOn.name.equals(name)) {
            throw new NameException("用户名错误");
        }
        if (!LogOn.password.equals(password)) {
            throw new PasswordException("密码错误");
        }
        System.out.println("登录成功");
    }
    //异常的检查
    public static void main(String[] args) {
        try {
            logon("fly","123456");
        }catch (NameException e) {
            e.printStackTrace();
            System.out.println("用户名错误");

        }catch (PasswordException e) {
            e.printStackTrace();
            System.out.println("密码错误");

        }
    }

}

你可能感兴趣的:(JavaSE知识点,java)