Java 异常

1.先通过一张图片了解一下有什么异常

在Java中,Throwable 是所有可抛出对象的超类。它有两个主要的子类:ErrorException,它们都直接继承自 Throwable

  1. Error是指编译器不能处理的错误,需要程序员手动去解决,表示严重的问题,通常由于系统故障或虚拟机自身的问题引起,如内存不足(OutOfMemoryError)、栈溢出(StackOverflowError)等

  2. Exception是指可以通过代码来解决的异常,它的子类分为受查异常非受查异常(RuntimeException)

  3. 受查异常:指需要通过try-catch或者throws来声明的异常

  4. 非受查异常:不需要以上操作

 2.处理异常的5个关键字

throw try catch finally throws

2.1 throw 与 throws

(这里即使不使用 try-catch 也同样可以执行 )

如果抛出的是受查异常,也就是除了RuntimeException 之外的异常,就需要throws来声明

第一个throws是声明

第二个throw是抛出异常

在方法体内声明抛出一个异常,这样调用这个方法的任何代码都必须捕获这个异常

1中我们可以看到抛出异常的同时后续代码不会执行

2中看到捕获异常之后执行接下来代码,并用printStackTrace来答应 异常的堆栈跟踪信息

3中打印出参数中的字符串

注意:

1.throw必须写在方法体内部

2.抛出的是RuntimeException或者它的子类,可以不用处理

3.如果不是则需要处理,否则无法通过编译

4.异常一旦抛出,其后的代码不会执行

2.2 try-catch

通常是这样的

try{

要执行的代码

}catch(异常类型){

.......

}

catch (ArrayIndexOutOfBoundsException e)

也可以这样写

catch (NullPointerException | ArrayIndexOutOfBoundsException e)

但是不推荐,这样不知道捕获的是那个异常

写两个catch,但是其中一个捕获到下一个不会捕获

public static void main(String[] args) {
        int[] array = {1,2,3};
        try{
            System.out.println(array[55]);
            array = null;
            System.out.println(array[0]);

        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("数组越界异常。。。");
        }
        catch (NullPointerException e){
            System.out.println("空指针异常。。。");
        }
        System.out.println("after");
    }

可以修改成这样

public static void main(String[] args) {
        int[] array = {1,2,3};
        try{
            System.out.println(array[55]);

        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("数组越界异常。。。");
        }try{
            array = null;
            System.out.println(array[0]);
        }
        catch (NullPointerException e){
            System.out.println("空指针异常。。。");
        }
        System.out.println("after");
    }

 有不知道的异常类型可以用Exception来兜底,前提是Exception在后,也就是父类在后

catch (ArrayIndexOutOfBoundsException e){
            System.out.println("数组越界异常。。。");
        }
        catch (Exception e){
            System.out.println("异常。。。");
        }

 

 注意:

1.try块内抛出异常位置之后的代码不会执行

2.有多个异常类型与catch中捕获类型不匹配的,不被捕获会继续往外抛,直到JVM收到中断程序

3.try中抛出多个不同异常对象,必须使用多个catch来捕获,而异常之间如果具有父子关系,需要子类在前,父类在后

2.3 finally

上面说到throw抛出异常之后并不会执行接下来的代码

finally可以在抛出异常之后继续执行

那它的作用是什么呢

 public static int func() {
        Scanner scanner = null;
        try{
            scanner = new Scanner(System.in);
            int data = scanner.nextInt();
            return data;
        }catch (InputMismatchException I){
            I.printStackTrace();
        }finally {
            System.out.println("finally 中的代码。。。");
            scanner.close();
        }
        return 0;
    }

    public static void main(String[] args) {
        func();
    }

可以关闭没有关闭的程序,防止浪费 

finally {
            System.out.println("finally 中的代码。。。");
            scanner.close();
        }

3.处理流程

1.先执行try中代码

2.如果try中的代码出现异常,就会结束try中的代码

3.此时catch中的异常类型匹配的话就会执行catch中的代码

4.如果没有的话就会向上传递到上层调用者

5.一直到main方法还没有处理异常,就会交给JVM处理,此时程序就会异常终止

6.无论如何会执行finally的代码

4.自定义异常

创建一个类型继承想继承的异常,并创建继承类型的方法

public class UserNameException extends RuntimeException{
    public UserNameException() {
        super();
    }
    public UserNameException(String message) {
        super(message);
    }
}

这里写了一个登录系统,当用户名和密码不正确的时候会抛出异常 

class User{
    private String UserName;
    private int UserPassword;

    public String getUserName() {
        return UserName;
    }

    public void setUserName(String userName) {
        UserName = userName;
    }

    public int getUserPassword() {
        return UserPassword;
    }

    public void setUserPassword(int userPassword) {
        UserPassword = userPassword;
    }

    public void login(String name, int password){
        if(!UserName.equals(name)){
            throw new UserNameException("用户名错误。。。");
        }
        if (UserPassword != password ){
            throw new UserPasswordException("密码错误。。。");
        }
        System.out.println("登录成功!");
    }
}

public class login {


        public static void main(String[] args) {
            User user = new User();
            user.setUserName("zack");
            user.setUserPassword(666);

            try{
                user.login("zack",666);
            }catch (UserNameException e){
                e.printStackTrace();
            }catch (UserPasswordException e){
                e.printStackTrace();

            }
        }
}

 

  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值