详解 异常的处理方式

(请关注本人 “异常” 总集篇博文——《详解 异常》

异常的处理方式:

异常处理的两种方式

  1. try-catch 式
  2. throws 式

try-catch式
本人先通过一张图来展示下 try-catch式运行顺序
try-catch语句 的运行顺序至于finally 的内容,则是不论try内是否发生了异常,都会运行的语句,哪怕在try-catch 的内部return ,也会在return前运行。

现在,本人来展示下try-catch式的两种格式

try…catch…finally格式

try {
可能出现问题的代码 ;
} catch(异常名 变量名) {
针对问题的处理 ;
} finally {
释放资源;
}
(有时候finally那个代码块我们可以不用写)

那么,本人现在来展示下异常的 try-catch式 中的 try…catch…finally的格式 的处理方式:
本人来解决“内存泄漏”的问题:

package about_io;

import java.util.Scanner;

public class Test {
	
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		
		try {
			int num;
			num = in.nextInt();
			System.out.println(num);
		} catch (Exception e) {	
		} finally {		//finally : 无论是否发生异常,都会执行。(可用于解决内存泄漏问题)
			System.out.println("结束输入");
			in.close();
		}		
	}	
	
}

那么,我们再来运行一遍,看一下结果:
在这里插入图片描述

try…catch…格式

try {
可能出现问题的代码 ;
} catch (异常名1 变量名1){
对异常的处理方式 ;
} catch (异常名2 变量名2){
对异常的处理方式 ;
}....

现在,本人来讲解下 使用 try-catch格式注意事项

注意事项:

  1. 能明确的 异常尽量明确
  2. 多个异常类,如果是平级关系在前在后没关系
  3. 多个异常类,存在继承关系父类异常要放在后面

为了验证上面的语法条件约束,本人来给出一个错误的例子:

package about_io;

public class Test {
	 public static void main(String[] args) {
	        int a = 1;
	        int b = 0;

	        int[] arr={1,2};
	        arr=null;
	        //try里面一般放置,有可能会出现问题的代码
	        //catch(某种异常) 一旦出现某种异常,catch 就会捕获该异常
	        //一旦try种出现该种异常,那么相应的cathe就会执行
	        //捕获异常的注意事项:
	        //1.能明确的 异常,尽量明确
	        //2.多个异常类,如果是平级关系,在前在后没关系
	        //3,多个异常类,存在继承关系,父类异常要放在后面
	        try {
	            System.out.println(a / b); //这行代码有可能会出现异常
	            System.out.println(arr.length);

	        } catch (Exception e){
	            System.out.println("未知异常");
	        } catch (ArithmeticException e){
	            //一旦遇到这个异常,怎么去处理
	            System.out.println("除数为0了");
	        } catch (NullPointerException e){
	            System.out.println("空指针异常");
	        } 

	        System.out.println("下面的程序");
	    }
}

在这里插入图片描述
可以看到,当我们在捕获父类异常后再来捕捉子类异常,编译器就会报错

但是在JDK7之后,我们也可以将多异常写成如下格式:

try {
可能出现问题的代码 ;
}catch(异常名1 | 异常名2 | .... 变量名){
对异常的处理方案 ;
}

这样的处理方式,相对于上面的处理方式,有如下优缺点

好处:
就是简化了代码
弊端:
对多个异常的处理方式是一致的

但是,这种处理方式是有条件的:

新式catch结构 的 条件

条件:
多个异常之间只能是平级的关系,不能出现子父类的继承关系

为了验证上面的语法条件约束,本人来给出一个错误的例子:

package about_io;

public class Test {
	 public static void main(String[] args) {
	        int a = 1;
	        int b = 0;

	        int[] arr={1,2};
	        arr=null;
	        
	        try {
	            System.out.println(a / b); //这行代码有可能会出现异常
	            System.out.println(arr.length);
	            
				//多个异常之间只能是平级的关系,不能出现子父类的继承关系
	        } catch (ArithmeticException | NullPointerException | Exception e){	
	            System.out.println("发生了异常");
	        } 

	        System.out.println("下面的程序");
	    }
}

在这里插入图片描述
最后,本人再来强调一个try-catch式 的语法 —— catch的{}中不能是空


throw式

与try-catch式 的使用区别:
定义功能方法时,需要把出现的问题暴露出来让调用者去处理。
那么就通过throws在方法上标识

在上述文段中,本人讲解了两个关键字——throw和throws。
现在,本人来讲解下两者之间的区别:

  1. throws
    用在方法声明后面,跟的是异常类名
    可以跟多个异常类名,用逗号隔开
    表示抛出异常,由该方法的调用者来处理
    throws表示出现异常的一种可能性,并不一定会发生这些异常
  2. throw
    用在方法体内,跟的是异常对象名
    只能抛出一个异常对象名
    这个异常对象可以是编译期异常对象,可以是运行期异常对象
    表示抛出异常,由方法体内的语句处理
    throw则是抛出了异常,执行throw则一定抛出了某种异常

那么,本人来展示下如何使用throw式异常处理手段:
本人来给出一个例子:

package about_io;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class Test {
	
	public static void main(String[] args) throws SQLException {
		doSomething();
	}
	
	public static void doSomething() throws SQLException {
		Connection connection = null;
		PreparedStatement statement = connection.prepareStatement("abc");
		statement.setObject(1, "xbw");
	}
	
}

(这里的代码是本人后期课程所要讲解的,现在无需理解,本人仅借此展示 异常的throw式的使用)
那么,我们来看一下运行结果:
在这里插入图片描述
可以看到,我们若使用throw式,那么当出现异常时,必定会在控制台报出,
且调用含有throw式的方法的方法,就要对该异常进行处理。

那么,关于throw式处理异常的手段,本人还有一点要说明:
说明

  1. 子类在重写父类方法时,父类方法没有抛出异常子类不能抛出
  2. 子类不能抛出 父类没有抛出过的异常
  3. 子类方法上,抛出的异常不能比父类大,只能比父类小,或跟父类一样

(“异常” 总集篇博文——《详解 异常》
(本人“I/O流”总集篇博文链接:https:////www.cnblogs.com/codderYouzg/p/12418404.html

posted @ 2020-03-05 09:18  在下右转,有何贵干  阅读(499)  评论(0编辑  收藏  举报