JAVA异常处理机制(基础知识)

JAVA异常处理机制

一、异常概述

       世界上最真情的相依,是你在try我在catch,无论你发神马脾气,我都默默接受,静静处理。

       现在让我们来谈谈JAVA中的异常,嘻嘻。。。
       为了应对运行期间可能出现的错误,提高程序的的稳健性,Java中定义了强大的异常处理机制。Java的异常机制在增强程序稳健性的同时(围绕异常声明,在编译期间就具有严格的异常制度),增强了业务代码的逻辑性和连贯性(通过try-catch,避免了C等语言下的业务逻辑代码和异常检测代码严重混合)。在编程中,如果程序出现了问题,我们没有做任何处理,最终jvm会做出默认的处理。把异常的名称,原因及出现的问题等信息输出在控制台,同时会结束程序。如果我们用try..catch处理,在try里面发现问题后,jvm会帮我们生成一个异常对象,然后把这个对象抛出,和catch里面的类进行匹配。如果该对象是某个类型的,就会执行该catch里面的处理信息。

1、异常分类

请看下面这个情景
今天天气很好,张三出去旅游。骑着自行车,去山里面呼吸新鲜空气。但是张三现在遇到下面三个问题。
问题1:山路塌陷了,张三及时停住了,但是过不去了。严重的问题。
问题2:张三出门推自行车,发现气没了,把气吹起来。出发前就应该检查的问题。
        问题3张三骑着车在山路上惬意的行驶着,山路两边是有小石子的,中间是平坦的水泥路。一直在平坦的水泥路上行驶是没有任何问题的,但是呢,他偏偏喜欢 骑到小石子上,结果爆                        胎了。旅游的过程中出现的问题。no zuo no die。

程序的异常:Throwable
严重问题:Error 我们不处理。这种问题一般都是很严重的,比如说内存溢出。
一般问题:Exception
编译期问题:不是RuntimeException的异常 必须进行处理的,因为你不处理,编译就不能通过。

运行期问题:RuntimeException这种问题我们也不处理,因为是你的问题,而且这个问题出现肯定是我们的代码不够严谨,需要修正代码的。


对应上面的情景:
Error:走到半路上,发生山路塌陷,或者出现了泥石流,这个问题很严重,不是张三能够立马解决的。
Exception:出门前,张三要看看车轮子以及车链子等是否还在
RuntimeException:在骑车的过程中,有好路不走,偏偏要走石子路
让我们通过下面的图具体看看JAVA中的异常
   异常体系结构图:

二、异常处理机制

1、异常的处理一:

A:JVM的默认处理
把异常的名称,原因,位置等信息输出在控制台,但是呢程序不能继续执行了。
B:自己处理
a:try...catch...finally
自己编写处理代码,后面的程序可以继续执行
b:throws
把自己处理不了的,在方法上声明,告诉调用者,这里有问题

示例代码:

public class ExceptionDemo {
	public static void main(String[] args) {
        int a = 10;
		int b = 0;
		int[] arr = { 1, 2, 3 };
		// 爷爷在最后
		try {
			System.out.println(a / b);
			System.out.println(arr[3]);
			System.out.println("这里出现了一个异常,你不太清楚是谁,该怎么办呢?");
		} catch (ArithmeticException e) {
			System.out.println("除数不能为0");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("你访问了不该的访问的索引");
		} catch (Exception e) {
			System.out.println("出问题了");
		}
	}
}	
看着上面的代码,对于多个异常的处理,我们或许觉得catch块过多,这样显得很臃肿,不利于程序的可读性,所以JDK7提供了一种新的解决方法,如下:
示例代码:

public class ExceptionDemo {
	public static void main(String[] args) {
        int a = 10;
		int b = 0;
		int[] arr = { 1, 2, 3 };
		try {
			System.out.println(a / b);
			System.out.println(arr[3]);
		} catch (ArithmeticException |ArrayIndexOutOfBoundsException e) {
			System.out.println("程序出问题了。。。");
		}
	}
}
以这种方式,代码是不是变的清晰了很多呢,嘻嘻。。。
注意:这种方式虽然简洁,但是也不够好。主要体现在如下两点。
第一,处理方式是一致的,其实在实际开发中,还是有些场合符合这个用法的,比如对数据库操作,我管你是插入失败,还是删除失败,总之我给你个信息---你操作失败。
第二,catch后面的异常必须是同级关系。

2、异常处理方式二

 有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。或者说,我处理不了,我就不处理了。为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出。
格式:
throws 异常类名
注意:这个格式必须跟在方法的括号后面。尽量不要在main方法上抛出异常。
    定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在方法上标识。

3、异常中要了解的几个方法

public String getMessage():异常的消息字符串
public String toString():返回异常的简单信息描述
  此对象的类的 name(全路径名),": "(冒号和一个空格) 
调用此对象 getLocalizedMessage()方法的结果 (默认返回的是getMessage()的内容)
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。把信息输出在控制台。


三、自定义异常

java不可能对所有的情况都考虑到,所以,在实际的开发中,我们可能需要自己定义异常。而我们自己随意的写一个类,是不能作为异常类来看的,要想你的类
是一个异常类,就必须继承自Exception或者RuntimeException。继承自Exception是编译时的异常,继承RuntimeException是运行时期的异常。
示例代码:

public class MyException extends Exception {
	public MyException() {
	}

	public MyException(String message) {
		super(message);
	}
}
/*
 * 自定义异常测试类
 */
public class StudentDemo {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入学生成绩:");
		int score = sc.nextInt();

		Teacher t = new Teacher();
		try {
			t.check(score);
		} catch (MyException e) {
			e.printStackTrace();
		}
	}
}

public class Teacher {
     //如果你自定义的异常时继承自RuntimeException,是不需要throws MyException的
	public void check(int score) throws MyException {
		if (score > 100 || score < 0) {
			throw new MyException("分数必须在0-100之间");
		} else {
			System.out.println("分数没有问题");
		}
	}
}

四、面试题举例

1、final, finally, finalize的区别。

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
JVM不保证此方法总被调用。

2、error和exception有什么区别?

error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 exception表示一种设计或实现问题。
也就是说,它表示如果程序运行正常,从不会发生的情况。

3、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?

throws捕获并向外抛出异常
throw抛出异常
try catch是内部捕获异常并做自定义处理
finally是无论是否有异常都会被处理的语句,除非在finally前存在被执行的System.exit(int i)时除外
4、throws和throw的区别?
throws用在方法声明后面,跟的是异常类名,可以跟多个异常类名,用逗号隔开,表示抛出异常,由该方法的调用者来处理,throws表示出现异常的一种可能性,并不一定会发生这些异常
throw用在方法体内,跟的是异常对象名,只能抛出一个异常对象名,表示抛出异常,由方法体内的语句处理,throw则是抛出了异常,执行throw则一定抛出了某种异常

5、如果catch里面有return语句,请问finally里面的代码还会执行吗?

 如果会,请问是在return前,还是return后。
 会。前。
 准确的说,应该是在中间。

看下面的程序:

public class FinallyDemo {
	public static void main(String[] args) {
		System.out.println(getInt());
	}

	public static int getInt() {
		int a = 10;
		try {
			System.out.println(a / 0);
			a = 20;
		} catch (ArithmeticException e) {
			a = 30;
			return a;
			/*
			 * return a在程序执行到这一步的时候,这里不是return a而是return 30;这个返回路径就形成了。
			 * 但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40
			 * 再次回到以前的返回路径,继续走return 30;
			 */
		} finally {
			a = 40;
			//return a;//如果这样结果就是40了。
		}
		 return a;
	}
}
运行结果是30、理由如上






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值