Java异常处理-2-JVM异常处理方式和try catch处理异常

       前面我们大概了解了什么是异常和为什么要处理异常。这篇我们先通过了解JVM是如何默认处理异常,然后我们是如何主动去捕获和处理异常的。

1.JVM处理异常的方式

      在Java中,Java虚拟机(JVM)是如何处理异常的呢?,在执行Main函数的时候,如果运行过程中遇到异常问题,有两种处理方式:1)自己将该问题处理,然后继续运行 2)自己没有针对该问题处理方式,只有交给调用Main的JVM来处理。而JVM有一个默认的异常处理机制,遇到异常,抛出异常,和打印异常信息,同时将程序停止运行。

      举例,算数运行,如果除数为空就报异常的,JVM就自动抛出异常,停止执行运行异常出现代码行后面的代码。

package exception;

public class Demo1_Exception {

	public static void main(String[] args) {
		
		int x = div(10,0);
		System.out.println(x);
	}
	
	public static int div(int a, int b) {
		return a / b;
	}

}

运行结果:

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at exception.Demo1_Exception.div(Demo1_Exception.java:12)
	at exception.Demo1_Exception.main(Demo1_Exception.java:7)

      这个异常是违背了算数法则而设计的一个异常类对象。这个JVM运行大概是这样去处理问题的:运行到第7行代码,JVM发现遇到了它处理不了的情况。原因是在第12行代码出现了除数为0的异常,调用了div()方法,得到的返回对象不是一个int类型,而是一个new ArithmeticException() 这样的一个异常对象,把一个异常对象赋值给x,x又是int类型,所以出了错误,中断了程序。


2.try catch主动去处理异常

      既然JVM默认是抛出异常,中断程序运行,所以,程序员在写代码的时候都应该小心,应该主动去捕获并处理异常。在Java中,我们通过try ... catch语句来主动处理异常。有时候,try catch还会和finally一起出现,所以try ... catch语句有多种写法。我们先来看看这三个关键字的含义。

1)try:是用来检测异常

2)catch:是用来捕获异常

3)finally:最终的意思,一般用来释放资源,例如关闭文件和断开数据库连接等。

2.1 try catch举例

package exception;

public class Demo1_Exception {

	public static void main(String[] args) {
	
		try{
			int x = div(10,0);
			System.out.println(x);
			
		} catch(ArithmeticException a) {
			System.out.println("除数为零!");
		}
	}
	
	public static int div(int a, int b) {
		return a / b;
	}

}

      这个时候运行代码会打印:除数为零!,而不会抛出异常,这个时候程序就没有中断,打印了这个错误,还可以继续执行下去。

2.2 多个try catch 举例

      大部分时候,我们都是使用多个catch的情况,下面举例一下,同时捕获边界越界和除数为零的异常。

package exception;

public class Demo1_Exception {

	public static void main(String[] args) {
	
		try{
			
			int[] arr = {11,22,33};
			int x = div(10,0);
			System.out.println(x);
			System.out.println(arr[5]);
			
		} catch(ArithmeticException a) {
			System.out.println("除数为零!");
		} catch(ArrayIndexOutOfBoundsException a) {
			System.out.println("数组索引越界了");
		} 
		
	}
	
	public static int div(int a, int b) {
		return a / b;
	}

}

      上面代码,写了两个catch代码块。第一个是捕获除数为零异常,第二个是捕获数组索引越界异常。运行代码,输出除数为零的。英文try里面最新监测到了除数为零的异常,里面就跳转到了对应捕获除数为零的代码块,这个时候就跳出了try catch整体范围,所以没有继续打印数组索引越界了的消息。你可以注销10 11行代码运行就可以打印数组索引越界了的消息。

       在实际的写代码中,我们一般也就和上面一样写几个可能出现的异常,然后后面添加一个Exception的捕获。Exception范围包括了所以的异常。所以,小范围的异常捕获需要写在Exception捕获语句前面。

package exception;

public class Demo1_Exception {

	public static void main(String[] args) {
	
		try{
			
			int[] arr = {11,22,33};
			int x = div(10,0);
			System.out.println(x);
			System.out.println(arr[5]);
			
		} catch(ArithmeticException a) {
			System.out.println("除数为零!");
		} catch(ArrayIndexOutOfBoundsException a) {
			System.out.println("数组索引越界了");
		} catch(Exception e) {
			System.out.println("出错了");
		}
		
	}
	
	public static int div(int a, int b) {
		return a / b;
	}

}

      上面第三个catch语句中捕获Exception异常的好处就是,能自动捕获所有的异常。即使你不写前面的除数为零和数组索引越界异常,只写一个Exception也能捕获到。这里就是执行了Exception e = new ArithmeticException(); 多态中的父类应用指向了子类对象。上面提到了finally关键字,我们后面来学习,finally关键字有特定的功能。






猜你喜欢

转载自blog.csdn.net/u011541946/article/details/80721671