一.认识异常:
异常是程序中导致程序中断的一种指令流。
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();
}
}
}
本程序的开发已经满足基本的要求,不管是否出现异常,都会将异常交被给调用处输出,同时每次操作都会指定固定的输出。