Java程序设计--异常处理

一、什么是异常?

异常时指程序在执行期间发生的事件,是导致程序中断运行的正常指令流。

举一个简单的例子:

public class ExceptionDemo01 {
	public static void main(String[] args) {
		int x=10;
		int y=0 ;
		int m=x/y;//除数为0出现异常
		System.out.println("m="+m);
		int n=x+y;
		System.out.println("n="+n);
	}
}

上面的程序在编译的时候没有任何错误,但是运行时就会产生异常中断的执行,并立即退出运行,后面的语句都不会再执行,由此可见,出现异常会改变原先的执行顺序,导致一系列的严重后果。异常的本质是在一个程序执行期间发生的一个事件,该事件中断了正常的执行流程。在Java发放内部发生错误时,该方法会创建一个Exception类型的对象返回给jvm,JVM会找一个合适的方法类来处理这个异常。

Java中所有的异常类都是继承自Throwable类,就是说所有的异常类都是Throwable的子类;Throwable类有两个子类,一个是Error,另一个是Exception类,他们是异常的两个分支。

Error描述的是Java运行系统中的内部错误以及资源耗尽情况下的错误,应用程序不能跑出这个错误。Exception类下面同样有两个分支,一个是运行时异常(非必检异常),一个是非运行是异常(必检异常)。

常见的几种异常:

1.1算术异常:

int x=10;
int y=0 ;
int m=x/y;//除数为0出现异常

1.2数组越界异常:

int arr[] ={1,2,3};
System.out.println(arr[3]);

1.3数组存储异常:

boolean b[]={false,false,false};
int arr[]={1,2,3};
System.out.println(arr,0,b,0,1);

1.4对象转化异常:

Object obj = new Object();
int in[]=(int [])obj;

1.5空指针异常:

String str = null;
System.out.println(str.length());

二、异常的两种处理机制(要么进行抛出throws,要么进行捕获try ...catch...finally)

2.1try...catch处理异常的格式

	try {
		//可能出现异常的语句
	}catch(异常类型1 异常信息对象1){
		//对异常 信息的一种处理
	}catch(异常类型2 异常信息对象2){
		//对异常信息的处理语句
	}finally {
		//一定会运行的语句
	}

其实在一个try中如果有多个异常,可以采用多个catch来进行捕获异常。一般而言,try不能单独的存在,它一般可以和try...catch...finally,  try...catch..以及try...finally组合try,catch,finally这三个关键字都不能单独的存在。

举个简单的数据越界的例子:

public class ExceptionDemo {
	public static void main(String[] args) {
		int arr[] = {1,2,3};
		try {
			System.out.println("arr[0]="+arr[0]);
			
			System.out.println("arr[3]="+arr[3]);
			
		}catch(ArrayIndexOutOfBoundsException e){
			
			System.out.println("异常信息是:"+e);
			
		}finally {
			System.out.println("无论是否有异常,都会执行finally语句");
		}
	}
}

运行结果截图:


一般大家都会认为finally里面是必须能够执行到的语句,但是有两点需要注意,finally语句是执行不到的

在finally语句执行之前执行了System.exit(0),退出运行,以及在执行finally之前所有的线程都死亡,则finally也不会再执行

public class ExceptionDemo {
	public static void main(String[] args) {
		int arr[] = {1,2,3};
		try {
			System.out.println("arr[0]="+arr[0]);
			
			System.out.println("arr[3]="+arr[3]);
			
		}catch(ArrayIndexOutOfBoundsException e){
			System.exit(0);//测试finally是否会依然执行
			System.out.println("异常信息是:"+e);
			
		}finally {
			System.out.println("无论是否有异常,都会执行finally语句");
		}
	}
}

运行结果:


可以看出finally里面的语句不会再执行。

当有多个catch的时候就会出现一个问题,catch里面所捕获的异常的范围大小的顺序,我们知道Exception的范围是最大的,那么多个catch里面的异常顺序该如何来进行排列呢,下面让我们来看一个实例:

import java.util.Scanner;

public class ExceptionDemo {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int arr[] = new int[5];
		try {
			System.out.println("请输入数组元素:");
			for(int i=0;i<arr.length;i++) {
				arr[i] = scan.nextInt();
			}
			System.out.println("请输入需要取出的数组的下标:");
			int n = scan.nextInt();
			System.out.println("arr["+n+"]="+arr[n]);
			int m = arr[3]/0;
			System.out.println("m="+m);
		} catch (ArrayIndexOutOfBoundsException e1) {
			e1.printStackTrace();
			System.out.println("数组越界异常信息:");
		}catch (IndexOutOfBoundsException e2) {
			e2.printStackTrace();
			System.out.println("越界异常信息:");
		}catch (Exception e) {
			e.printStackTrace();
			System.out.println("Exception异常信息");
		}
		System.out.println("***程序结束***");
	}
}

对于有多个异常信息需要去捕获,那么就应该去在catch中对需要进行捕获的异常信息进行排序,范围小的在前面,范围大的在后面。

注意:在重写方法时遇到了异常,应该注意:

重写方法异常时,可以抛出与被重写方法相同的异常或者被重写方法异常的子类异常。

如果父类的方法没有声明抛出异常,那么子类重写方法不可以声明抛出检查异常,但是可以抛出不检查异常。

如果父类的方法声明抛出异常,包括自定义的异常,那么子类覆盖方法可以不声明抛出异常。但是,如果子类重写方法要抛出异常的话,只能抛出与被重写方法相同的异常或者被重写方法异常的子类,不能是其他检查异常。

三、throws声明异常

如果一个方法中抛出的异常没有在catch中找到合适的进行异常处理的程序,Java就会退出该方法。如果不想捕获,就可以进行抛出。下列代码中,主方法main()仅仅使用throws关键字,,没有使用try...catch语句。所以方法拥有的异常都会一直向上抛,抛给主方法,而主方法依然不做任何处理,那么此时就会抛给JVM,可是JVM就会调用默认异常处理程序处理,即中断程序的执行并退出。

public class ExceptionDemo02 {
	public static void arrException() throws FileNotFoundException {
		FileInputStream file = new FileInputStream("不存在的文档.txt");
	}
	public static void main(String[] args) throws Exception {
		arrException();
	}
}





猜你喜欢

转载自blog.csdn.net/huolan52/article/details/80638299