Java中的异常

一、异常的处理方式

1.JVM默认的处理方式:

把异常的名称,异常的原因及异常出现的位置等信息输出在了控制台

程序停止执行,下面的代码不会再执行了

代码演示:

package a11exceptiondemo;

public class ExceptionDemo1 {
    public static void main(String[] args) {
        System.out.println("语句1");
        System.out.println(2/0);//算数异常ArithmeticException
        System.out.println("语句2");
        System.out.println("语句3");
    }
}

控制台结果:

 

2.自己处理(捕获异常)

格式:

try{
    可能出现异常的代码;
}catch(异常类名 变量名){
    异常的处理代码;
}

好处:可以让程序继续往下执行,不会停止

代码演示:

package a11exceptiondemo;

public class ExceptionDemo2 {
    public static void main(String[] args) {
        int[] arr={1,2,3,4,5};


        try{
            System.out.println(arr[10]);
            //此处出现了异常,程序就会在这里创建一个ArrayIndexOutOfBoundsException对象
            //new ArrayIndexOutOfBoundsException();
            //拿着这个对象到catch的小括号中对比,看括号中的变量是否可以接收这个对象
            //如果能被接收,就表示该异常就被捕获(抓住),执行catch里面对应的代码
            //当catch里面的代码执行完毕,继续执行try...catch体系下面的其他代码
        }catch(ArrayIndexOutOfBoundsException e){
            //如果出现了异常如何处理
            System.out.println("索引越界了");
        }
        System.out.println("语句1执行了吗");
    }
}

 运行结果:

四个问题:
1.如果try中没有遇到问题,怎么执行?

会把try里面所有的代码全部执行完毕,不会执行catch里面的代码

注意:只有当出现了异常才会执行catch里面的代码

代码演示:

package a11exceptiondemo;

public class ExceptionDemo3 {
    public static void main(String[] args) {
        int[] arr={1,2,3,4,5};
        try{
            System.out.println(arr[0]);
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("索引越界了");
        }
        System.out.println("语句1执行了吗");
    }
}

运行结果:

 

2.如果try中可能会遇到多个问题,怎么执行?

会写多个catch与之对应

细节:如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面

如果父类写在上面:会报如下错: 

 

在JDK7以后,我们可以在catch中同时捕获多个异常,中间用 | 隔开

表示如果出现了A异常或者B异常的话,采取同一种解决方案

3.如果try中遇到的问题没有被捕获,怎么执行?

此时相当于try...catch中的代码白写了,最终还是会交个虚拟机进行处理

代码示范:

package a11exceptiondemo;

public class ExceptionDemo5 {
    public static void main(String[] args) {
        int[] arr={1,2,3,4,5};
        try{
            System.out.println(arr[10]);//ArrayIndexOutOfBoundsException
        }catch(NullPointerException e){
            System.out.println("空指针异常");
        }
        System.out.println("语句1执行了吗");
    }
}

运行结果:

 

4.如果try中遇到了问题,那么try下面的其他代码还会执行吗?

如果try中遇到了问题,那么try下面的其他代码就不会执行了,直接跳转到对应的catch当中,执行catch里面的语句体,但如果没有找到对应的catch与之匹配,那么还是会交给虚拟机进行处理

Throwable的成员方法

public String getMessage()--------->返回throwable的详细信息字符串

public String toString()-------->返回此可抛出的简短描述

public void printStackTrace()------->把异常的错误信息输出在控制台

细节

printStackTrace()方法只会打印信息,不会停止程序运行

在底层是利用System.err.println进行输出,把异常的错误信息以红色字体输出在控制台

代码示范:

package a11exceptiondemo;

public class ExceptionDemo8 {
    public static void main(String[] args) {
        int[] arr={1,2,3,4,5};
        try {
            System.out.println(arr[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
//            String message = e.getMessage();
//            System.out.println(message);//Index 10 out of bounds for length 5

//            String s = e.toString();
//            System.out.println(s);//java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5

            e.printStackTrace();
        }
        System.out.println("语句1执行了吗");
    }
}

运行结果:

3.抛出异常

throws:写在方法定义处,表示声明一个异常,告诉调用者,使用本方法可能会有哪些异常

public void  方法() throws 异常类名1, 异常类名2...{

}

编译时异常必须要写

运行时异常可以不写

throw:写在方法内,结束方法,手动抛出异常对象,交给调用者,方法中下面的代码不再执行了

public void 方法(){

        throw new NullPointerException

}

代码示范:

package a11exceptiondemo;

public class ExceptionDemo9 {
    public static void main(String[] args) {
        //定义一个方法求数组最大值
        int[] arr=null;
        int max=getMax(arr);
        System.out.println(max);

    }

    public static int getMax(int[] arr) /*throws NullPointerException,ArrayIndexOutOfBoundsException*/{
        //这俩都是运行时异常可以不写
        if(arr==null){
            //手动创建一个异常对象,并把这个异常交给方法的调用者处理
            //此时方法就会结束,下面的代码不会再执行了
           throw new NullPointerException();
        }
        if(arr.length==0){
            throw new ArrayIndexOutOfBoundsException();
        }
        System.out.println("看看我执行了吗");
        int max=arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(arr[i]>max){
                max=arr[i];
            }

        }
        return max;
    }
}

抛出:告诉调用者出错了  捕获:不让程序停止 

二、练习:键盘录入数据

需求:键盘录入姓名和年龄,姓名的长度再3~10之间,年龄的范围为18~40岁

超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止

提示:需要考虑用户在键盘录入时的所有情况

比如录入年龄时超出范围,录入年龄时录入了abc等情况

Friend类:

package a11exceptiondemo;

public class Friend {
    private String name;
    private int age;

    public Friend() {
    }

    public Friend(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        int len=name.length();
        if(len<3||len>10){
            throw new RuntimeException();
        }
        this.name = name;
    }
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age<18||age>40){
            throw new RuntimeException();
        }
        this.age = age;
    }

    public String toString() {
        return "Friend{name = " + name + ", age = " + age + "}";
    }
}

测试类:

package a11exceptiondemo;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        //1.创建键盘录入的对象
        Scanner sc = new Scanner(System.in);
        //2.创建朋友对象
        Friend f = new Friend();
        while (true) {
            //3.接收朋友的姓名
            try {
                System.out.println("请输入朋友的名字");
                String name = sc.nextLine();
                f.setName(name);
                //4.接受朋友的年龄
                System.out.println("请输入朋友的年龄");
                String ageStr = sc.nextLine();
                int age = Integer.parseInt(ageStr);
                f.setAge(age);
                //如果所有的数据都是正确的,那么跳出循环
                break;

            } catch (NumberFormatException e) {
                System.out.println("年龄格式有误,请输入数字");
            } catch (RuntimeException e) {
                System.out.println("姓名的长度或年龄的范围有误");
            }
        }
        System.out.println(f);
    }
}

运行结果:

 

三、自定义异常

意义:就是为了让控制台的报错信息更加的见名知意

步骤:①定义异常类②写继承关系③空参构造④带参构造

代码示范:

Friend类:

package a12Test;

public class Friend {
    private String name;
    private int age;

    public Friend() {
    }

    public Friend(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        int len=name.length();
        if(len<3||len>10){
            throw new NameForamtException(name+"格式有误,长度应该为3~10");
        }
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        if(age<18||age>40){
            throw new AgeOutOfBoundsException(age+"超出了范围");
        }
        this.age = age;
    }

    public String toString() {
        return "Friend{name = " + name + ", age = " + age + "}";
    }
}

名字格式异常类:

package a12Test;

public class NameForamtException extends RuntimeException{
    public NameForamtException() {
    }

    public NameForamtException(String message) {
        super(message);
    }
}

年龄超出范围异常类:

package a12Test;

public class AgeOutOfBoundsException extends RuntimeException{
    public AgeOutOfBoundsException() {
    }

    public AgeOutOfBoundsException(String message) {
        super(message);
    }
}

测试类:

package a12Test;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        //1.创建键盘录入的对象
        Scanner sc = new Scanner(System.in);
        //2.创建朋友对象
        Friend f=new Friend();
        while (true) {
            //3.接收朋友的姓名
            try {
                System.out.println("请输入朋友的名字");
                String name = sc.nextLine();
                f.setName(name);
                //4.接受朋友的年龄
                System.out.println("请输入朋友的年龄");
                String ageStr = sc.nextLine();
                int age = Integer.parseInt(ageStr);
                f.setAge(age);
                //如果所有的数据都是正确的,那么跳出循环
                break;

            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (NameForamtException e) {
                e.printStackTrace();
            } catch (AgeOutOfBoundsException e) {
                e.printStackTrace();
            }
        }
        System.out.println(f);
    }
}

运行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值