二十三、Java异常捕获与处理

异常的基本概念

    在开发的过程中,有时程序会出现不可避免、不可预测的错误情况发生,我们称为异常,想象一下, 当整个程序,在某个部分出现异常,导致程序的阻塞,程序没法正常继续的进行下去。为了避免这种情况的发生,加强程序的健壮性,所以Java加入的异常机制,用来捕获和处理异常


异常处理有如下几个特点

    (1)不需要打乱程序的运行顺序,如果没有捕获到异常,那么程序的运行不会受到影响

    (2)不需要靠输出或者方法的返回值来判断是否出现错误

    (3)采用集中的方式来处理错误,能够根据异常的种类的不同来进行对应的异常处理操作


常见的java异常

    (1)ArithmeticException算术异常:当算数运算中出现除零的运算就会出现这样的异常

    (2)NullPointerException空指针异常:当没有给对象开辟内存空间,却使用了该对象时,就会出现空指针异常

    (3)FileNotFoundException文件未找到异常:当程序试图打开一个不存在的文件时,就会出现文件未找到异常,经常是因为程序员写错文件名字、路径写错或者U盘已经移除之类的情况导致文件未找到异常的发生

    (4)ArrayIndexOutOfBoundsException数组下标越界异常:数组的索引超过上限或者下限都会触发数组下标越界异常


异常的捕获与处理格式

    try{

            要检查的语句   

     }catch(异常类   异常对象){

            捕捉到对象的异常需要处理的语句

    }finally{

            一定会执行的代码块

    }

注意要点:

(1)程序通过try{}捕捉异常,try如果有异常发生,程序的运行便会中断,抛出“异常类所产生的对象”

(2)try{}抛出的异常对象会进入catch()判断是否是括号内想要捕获的异常,如果是,就会进入catch{}代码块内进行异常的处理,程序继续往下运行,可以有多个catch(){},即可以有多个异常对象,按类处理异常

 (3)finally{}程序无论是否捕获异常都会执行,一般用来关闭对象,比如Scanner sc,我们会在finally内sc.close();finally可写可不写


简单的异常捕获与处理演示

接下来我们举同样的例子,一个无异常的处理,一个加入异常处理,我们来看看异常处理的强大。

代码演示:

package demo;

//未加入异常的捕获和处理
public class ExceptionDemo {
	public static void main(String[] args) {
		int[] a = new int[5];
		//下列代码会出现数组下标越界异常
		a[10] = 15;
		System.out.println("测试值="+a[10]);
	}
}

代码结果:


 代码讲解:我们能够看到在程序编译时,程序不会有任何错误,当程序运行时,java会检测到异常,便由系统抛出异常信息,然后停止程序执行,我们能够看到最后一句并没有输出


------------------------------------我们来修改一下代码,加入异常的捕获和处理--------------------------------


代码演示:

package demo;

//加入异常的捕获和处理
public class ExceptionDemo {
	public static void main(String[] args) {
		
		try {
			int[] a = new int[5];
			//下列代码会出现数组下标越界异常
			a[10] = 15;
		} catch (ArrayIndexOutOfBoundsException e) {
			e.printStackTrace();
		}
		System.out.println("出现异常并且处理");
	}
}

代码结果:


代码讲解:我们可以看到,通过try-catch的使用,我们捕获了异常,并对异常进行了处理,最后一句的话,也进行了输出,能够看到,当程序加入了异常的捕获和处理,程序就不会一碰到异常就直接终止程序运行,而是处理完异常,继续往下执行。



异常对象e的使用

代码演示:

package demo;

public class ExceptionDemo {
	public static void main(String[] args) {
		try {
			int[] a = new int[5];
			//下列代码会出现数组下标越界异常
			a[10] = 15;
		} catch (ArrayIndexOutOfBoundsException e) {
			//调用异常对象e的方法
			System.out.println("--------------------------");
			e.printStackTrace();
			System.out.println("--------------------------");
			System.out.println(e.getMessage());
			System.out.println("--------------------------");
			Object obj = e.getClass();
			System.out.println(obj.toString());
			System.out.println("--------------------------");
		} finally {
			System.out.println("finally语句可按需求来写,无论是否捕获异常都一定会运行");
		}
	}
}

代码结果:


代码讲解:

(1)e.printStackTrace():直接输出异常类和所在的代码行数

(2)e.getMessage():返回代码出现错误的行数,返回类型是字符串类型

(3)e.getClass():返回异常对象的类型

我们最常用的就是e.printStackTrace



多个catch的使用

   

我们看看上图的继承关系,Throwable类为父类,Throwable下分为Error类,和Exception类

    Error类:通常是Java虚拟机(JVM)出现错误,用户无法在程序中解决

    Exception类:包含了一般性异常,这些异常通常可以由用户捕捉,通过处理,程序能够继续运行

Exception类分为两种:RuntimeException类和其他Exception类

    RuntimeException类:可以选择性的进行处理,如果不处理,JVM会默认处理,由用户选择是否处理

    其他类异常:强制性要求,用户必须处理异常


多个catch使用,一定要注意异常类的层次问题,多个catch,上面catch捕捉的异常类一定是比下面异常类所涵盖的范围小比如先catch(NullPointerException)后catch(RuntimeException),反过来就不行

代码演示:

package demo;

public class ExceptionDemo {
	public static void main(String[] args) {
		try {
			int[] a = new int[5];
			a[0] = 5;
			a[1] = 0;
			//下列代码出现算术异常
			a[2] = a[0] / a[1];
			//下列代码会出现数组下标越界异常
			a[10] = 15;

		} catch (ArrayIndexOutOfBoundsException e) {
			e.printStackTrace();
			System.out.println("同级别异常类前后都行");
		} catch (ArithmeticException e) {
			e.printStackTrace();
			System.out.println("同级别异常类前后都行");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("最高级异常类必须是最后一个catch里");
		}
	}
}

代码结果:


代码讲解:

1.捕捉到一个异常,进入了一个catch处理后,便退出了try-catch执行,并没有完全执行完try的代码

2.同级别异常类先后顺序无所谓,但高级的异常类一定在最后面写,顺序写错,程序会提示出错。


throws关键字

    有时候我们不想在方法里写try-catch语句,一般的都是交由调用者来处理,这时候我们就可以在方法上加上throws 异常类,然后由调用者来try-catch

代码演示:

package demo;

public class ExceptionDemo {
	public static double division(int a,int b) throws ArithmeticException{
		double result;
		result = a / b;
		return result;
	}
	public static void main(String[] args) {
		try {
			double res = division(9, 0);
			System.out.println("结果值为:"+res);
		} catch (ArithmeticException e) {
			e.printStackTrace();
			System.out.println("你错误的输入的除数,除数为0");
		}
	}
	
}

代码结果:




throw关键字

   目前为止,所有的异常类对象都是由JVM自动实例化,有时候用户希望能够根据自己的需求,进行自己实例化,就需要手动的抛出异常。

    与throws不同,可直接使用throw抛出一个异常,抛出时直接抛出异常类的实例化对象即可


我们来演示一个标准的异常处理格式,演示一下关键字throw和throws的配合使用

代码演示:

package demo;

public class ExceptionDemo{
	private static void setZero( int[] arr, int index )throws ArrayIndexOutOfBoundsException{
        System.out.println( "-------方法setZero开始-------" );
        try{
            arr[index] = 0;
        }
        catch( ArrayIndexOutOfBoundsException ex ){
        	//手动抛出了异常对象
            throw ex;
        }
        finally{
            System.out.println( "-------方法setZero结束-------" );
        }
     }     
    public static void main( String[] args ){
        int[] arr = new int[5];
        try{
            setZero( arr, 10 );
        }
        catch( ArrayIndexOutOfBoundsException e ){
            System.out.println( "异常:" + e );         
        }
    }
}

代码结果:



总结点评:异常的捕捉和处理,会使用try-catch,throws和throw使用即可,需要记住一些异常类。然后异常的学习到此就行,在实际操作过程中异常的使用还是比较少的,大家会用即可。


猜你喜欢

转载自blog.csdn.net/qq_38741971/article/details/80216157
今日推荐