一.认识异常:

异常是程序中导致程序中断的一种指令流。

1.不产生异常的代码:
package com.yooth.demo ;
public class TestDemo {
    public static void main(String args[]) {
        System.out.println("1.除法计算开始。");
        System.out.println("2.除法计算:" + (10/2));
        System.out.println("3.除法计算结束。");
    }
}

本程序中没有产生任何异常,所以代码将从头到尾顺序执行完毕。

2.产生异常:
package com.yooth.demo ;
public class TestDemo {
    public static void main(String args[]) {
        System.out.println("1.除法计算开始。");
        System.out.println("2.除法计算:" + (10/0));
        System.out.println("3.除法计算结束。");
    }
}

本程序执行结果:1.除法计算开始。 Exception in thread "main" java.lang.ArithmeticException: / by zero at com.yooth.demo.TestDemo.main(TestDemo.java:5) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131) 在本程序中产生了数学异常,由于程序没有进行异常的任何处理,所以默认情况下,会进行异常信息打印,同时将终止执行异常产生之后的代码。

二.处理异常:

Java针对异常的处理提供了三个核心的关键字:try、catch、finally,利用这三个字就可以组成以下异常处理格式:

try{
	//有可能出现异常的语句
}[catch(异常类型 对象){
	//异常处理;
catch(异常类型 对象){
	//异常处理;
catch(异常类型 对象){
	//异常处理;
}...][finally {
	;不管是否异常,都执行统一的代码
}]

在格式中已经明确表明。在try语句中捕获可能出现的异常代码。如果在try中产生了异常,则程序会自动跳转到catch语句中找到匹配的异常类型进行相应的处理。最后不管程序是否会产生异常,都会执行到finally语句,finally语句作为异常的统一出口,如果省略finally,则在catch()块运行结束后,程序继续向下执行。

1.应用异常处理格式:
package com.yooth.demo ;
public class TestDemo {
    public static void main(String args[]) {
        System.out.println("1.除法计算开始。");
        try {
            System.out.println("2.除法计算:" + (10/0));
            System.out.println(".....");
        }catch (ArithmeticException e) {
            System.out.println("***出现异常了***");
        }
        System.out.println("3.除法计算结束。");
    }
}

程序执行结果:1.除法计算开始。 ***出现异常了*** 3.除法计算结束。 1.本程序使用了异常处理语句格式,当程序中的数学计算出现异常后,异常会被try语句捕获,而后交给catch处理,这时程序会正常结束,而不会出现中断执行的情况。
2.这样的处理方式不能够明确地描述出异常类型,而且出现异常地目的是解决异常,所以为了能够进行异常地处理,可以使用异常类中提供的printStackTrace()方法进行异常信息的完整输出。

2.输出异常的完整信息:
package com.yooth.demo ;
public class TestDemo {
    public static void main(String args[]) {
        System.out.println("1.除法计算开始。");
        try {
            System.out.println("2.除法计算:" + (10/0));
            System.out.println(".....");
        }catch (ArithmeticException e) {
            e.printStackTrace();
        }
        System.out.println("3.除法计算结束。");
    }
}

程序执行结果:1.除法计算开始。 java.lang.ArithmeticException: / by zero at com.yooth.demo.TestDemo.main(TestDemo.java:6) 3.除法计算结束。 所有的异常类中都会提供printStackTrace()方法,而利用这个方法输出的异常信息,会明确地告诉用户是代码中地第几行出现了异常。

3.使用完整异常处理结构:
package com.yooth.demo ;
public class TestDemo {
    public static void main(String args[]) {
        System.out.println("1.除法计算开始。");
        try {
            System.out.println("2.除法计算:" + (10/0));
            System.out.println(".....");
        }catch (ArithmeticException e) {
            e.printStackTrace();
        }finally {
            System.out.println("### 无论是否异常都要执行 ###");
        }
        System.out.println("3.除法计算结束。");
    }
}

程序执行结果:1.除法计算开始。 java.lang.ArithmeticException: / by zero at com.yooth.demo.TestDemo.main(TestDemo.java:6) 3.除法计算结束。

4.修改程序,利用初始化参数传递数学计算数据:
package com.yooth.demo ;
public class TestDemo {
    public static void main(String args[]) {
        System.out.println("1.除法计算开始。");
        try {
            int x = Integer.parseInt(args[0]) ;
            int y = Integer.parseInt(args[1]) ;
            System.out.println("2.除法计算:" + (x/y));
            System.out.println(".....");
        }catch (ArithmeticException e) {
            e.printStackTrace();
        }finally {
            System.out.println("### 无论是否异常都要执行 ###");
        }
        System.out.println("3.除法计算结束。");
    }
}

在本程序中由于只处理了算术异常,所以当出现其他异常后,程序依然无法处理,会直接中断执行,但是通过执行也可以发现,此时即使没有处理地异常,finally也会正常执行,而 其他语句将不再执行。

5.加入多个catch进行异常处理:
package com.yooth.demo ;
public class TestDemo {
    public static void main(String args[]) {
        System.out.println("1.除法计算开始。");
        try {
            int x = Integer.parseInt(args[0]) ;
            int y = Integer.parseInt(args[1]) ;
            System.out.println("2.除法计算:" + (x/y));
            System.out.println(".....");
        }catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }catch (NumberFormatException e) {
            e.printStackTrace();
        }catch (ArithmeticException e){
            e.printStackTrace();
        } finally {
            System.out.println("### 无论是否异常都要执行 ###");
        }
        System.out.println("3.除法计算结束。");
    }
}

本程序在异常处理中加入了多个catch语句,这样就可以处理3种异常,并且这三种异常的处理形式完全相同,都是打印异常信息。

三.throws关键字:

throws关键字主要在方法定义上使用,表示此方法中不进行异常的处理,而是交给被调用处处理:

public class MyMath {
    public static int div(int x , int y)throws Exception {
        return x/y ;
    }
}

本程序定义了一个除法计算操作,但是在div()方法上使用了throws关键字进行声明,这样就表示在本方法中所产生的任何异常本方法都可以不用处理,而是直接交给程序的被调用处进行处理。由于div()方法上存在throws抛出的Exception异常,则当调用此方法时必须明确地处理可能会出现的异常。
调用以上的方法:

public class TestDemo {
    public static void main(String args[]) {
        try {
            System.out.println(MyMath.div(10,2));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

本程序由于MyMath类的div()方法定义上已经明确地抛出了异常,所以调用时必须写上异常处理语句,否则会在编译时出现语法错误。

四.throw关键字:

之前所有地异常类对象都是由JVM自动进行实例化操作地,而现在用户也可以自己手工地抛出实例化对象(手工调用异常类的构造方法),就需要通过throw完成。

package com.yooth.demo ;
public class TestDemo1 {
    public static void main(String args[]) {
        try {
            throw new Exception("自己定义的异常!") ;
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

本程序首先实例化了一个Exception异常类对象,然后利用throw进行抛出,这时就必须明确进行异常处理。

五.异常处理的标准格式:

异常处理除了最为常见的“try…catch”应用格式外,还存在一种结合“try、catch、finally、throw、throws”一起使用的异常处理格式。
我们要定义一个div()方法,而这个方法有以下一些要求:
1.在进行除法操作之前,输出一行提示信息
2.在除法操作执行完毕之后,输出一行提示信息
3.如果中间产生了异常,则应该交给被调用处来进行处理
4.为了保证计算结束之后可以正常地输出信息,则应该使用finally进行操作
5.为了保证异常可以交给被调用处使用,应该在方法声明上加上throws,而程序中也不应该处理异常。
实现要求:

package com.yooth.demo ;
class MyMath {
    public static int div(int x , int y)throws Exception {
        System.out.println("===== 计算开始 =====");
        int result = 0 ;
        try {
            result = x/y ;
        }catch (Exception e) {
            throw e ;
        }finally {
            System.out.println("===== 计算结束 =====");
        }
        return result ;
    }
}
public class TestDemo {
    public static void main(String args[]) {
        try {
            System.out.println(MyMath.div(10,0));
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

本程序的开发已经满足基本的要求,不管是否出现异常,都会将异常交被给调用处输出,同时每次操作都会指定固定的输出。