欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

异常的概述和分类

程序员文章站 2022-04-21 17:56:54
...

异常的概述和分类

异常的概述:
		异常就是java程序在运行时出现的错误。
异常的分类:
		编译期异常:非RuntimeException。
		运行期异常:RuntimeException及其子类,运行期异常我们自己可以解决,也可以不解决交由JVM	解决。JVM的默认处理方式是打印详细的异常信息,然后退出虚拟机。
自己处理运行期异常:
		我们可以使用try catch 来进行异常的捕获处理
       	try 里面放的是你认为有可能会出现异常的代码。
        catch(ArithmeticException e) catch 小括号里面定义的是,你将要捕获的何种异常。
        catch 大括号里面 放的是,一旦发生你捕获的这种异常,你的处理方式是什么。
        注意的有两点:
        	1.try里面尽可能放的是,有可能出现问题的代码。
       		2.一旦发生异常,异常的处理,不能空处理。
       		3.能明确的异常,尽量明确,不要拿Exception异常来明确。
        	4.捕获多个异常时,大的异常,放在最后面,平级关系的异常,谁前谁后无所谓。
案例:
1.JVM默认异常处理方式:
	public class Test1 {
    public static void main(String[] args) {
        System.out.println(11/0);
		System.out.println("之后的代码");
		System.out.println("之后的代码");
    }
}

结果:
	Exception in thread "main" java.lang.ArithmeticException: / by zero
		at Demo1.Test1.main(Test1.java:5)

	Process finished with exit code 1
        
	//如果使用JVM默认处理异常的机制,那么在处理完异常后,会直接关闭JVM,使得后续的代码无法运行。
 
        
2.使用Try{}catch(){}处理异常:
	//在程序运行异常后,捕获异常,但是不会讲JVM终止,会继续执行后续代码。
代码:
	public class Test1 {
    public static void main(String[] args) {
        try {
            System.out.println(11/0);
        }catch (ArithmeticException e){
            System.err.println("除数为0了");
        }
        System.out.println("之后的代码");
        System.out.println("之后的代码");
        System.out.println("之后的代码");
    }
}
	
结果:	
	除数为0了
	之后的代码
	之后的代码
	之后的代码

	Process finished with exit code 0
    
3.使用Try{}catch(){}处理多个异常:
代码:
	public class Test1 {
    public static void main(String[] args) {
        int[] arr={1,2};
        int[] arr1=null;
        try {
        	//在try里面,如果出现代码运行期异常,则直接去catch找寻对应的异常。
            System.out.println(arr[3]);
            System.out.println(11/0);
            System.out.println(arr1.length);
        }catch (ArithmeticException e){
            System.err.println("除数为0了");
        }catch (ArrayIndexOutOfBoundsException e){
            System.err.println("角标越界");
        }catch (NullPointerException e){
            System.err.println("空数组");
        }
        System.out.println("之后的代码");
        System.out.println("之后的代码");
        System.out.println("之后的代码");
    }
}
结果:
	角标越界
	之后的代码
	之后的代码
	之后的代码

	Process finished with exit code 0

案例:
	//判断键盘录入的数据是否为需求的数据。
	//如果不是,提醒重新输入。
	public class Test2 {
    public static void main(String[] args) {

        while (true) {
            Scanner sc = new Scanner(System.in);
        try {
            System.out.println("请输入一个整数:");
            int i = sc.nextInt();
            System.out.println(i);
            break;
        }catch (Exception e) {
            System.out.println("输入的格式错误,请重新输入:");
        }
        }
    }
}
结果:
	请输入一个整数:
    aa
    输入的格式错误,请重新输入:
    请输入一个整数:
    ww
    输入的格式错误,请重新输入:
    请输入一个整数:
    11
    11

    Process finished with exit code 0

throws和throw的区别

throws
        用在方法声明后面,跟的是异常类名
        可以跟多个异常类名,用逗号隔开
        表示抛出异常,由该方法的调用者来处理
        throws表示出现异常的一种可能性,并不一定会发生这些异常
        
throw
        用在方法体内,跟的是异常对象名
        只能抛出一个异常对象名
        这个异常对象可以是编译期异常对象, 可以是运行期异常对象
        表示抛出异常,由方法体内的语句处理
        throw则是抛出了异常,执行throw则一定抛出了某种异常
案例:
	public class Test3 {
     public static void main(String[] args) throws ParseException {
        int a = 10;
        int b = 0;
        double r = show(a, b);
        System.out.println(r);
        new SimpleDateFormat("yyyy-MM-dd").parse("2020-01-01");
    }

    private static double show(int a, int b) {
        double r = 0;
        if (b == 0) {
            throw new ArithmeticException("除数为零,解析异常");
        } else {
            r = a / b;
        }
        return r;
    }
}

结果:
	Exception in thread "main" java.lang.ArithmeticException: 除数为零,解析异常
	at Demo1.Test3.show(Test3.java:14)
	at Demo1.Test3.main(Test3.java:7)

	Process finished with exit code 1

自定义异常

为什么要有自定义异常?
		Java给给我们提供了很多异常类,来描述我们在开发中所遇到一些常见的问题,
        但是还是不足以,描述我们所遇到一些异常情况。
案例:银行取钱时,卡内余额不足
	public class MyTest {

    private static double money;

    public static void main(String[] args) {
        money = 100;

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的取款金额");
        double num = scanner.nextDouble();
        quKuan(num);

    }

    private static void quKuan(double num) {
        if(num<=money){
            money-=num;
            System.out.println("取款成功");
        }else{
            throw new NoMoneyException("余额不足异常");
        }
    }
}




class NoMoneyException extends RuntimeException {

    public NoMoneyException(String msg) {
    }
}

结果:
	请输入你的取款金额
	233
	Exception in thread "main" Demo1.NoMoneyException
	at Demo1.Test4.quKuan(Test4.java:23)
	at Demo1.Test4.main(Test4.java:14)

	Process finished with exit code 1

    

异常注意事项(针对编译期异常)

1.子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类,或者子类不抛出异常也是可以的。(父亲坏了,儿子不能比父亲更坏)
2.如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常,或者子类不抛出异常也是可以的。
3.如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws
	
如何使用异常处理
		原则:如果该功能内部可以将问题处理,try,如果处理不了,交由调用者处理,这是用throws
		区别:
			后续程序需要继续运行就try
			后续程序不需要继续运行就throws
			
如果JDK没有提供对应的异常,需要自定义异常。