Java_异常处理-程序员宅基地

技术标签: java  

这篇我们聊聊java中的异常。首先我们要知道什么是异常?

Exception:

exception翻译过来就是“意外”的意思。事实上,异常的本质就是程序的错误,包括程序逻辑错误和系统错误。错误在编写程序中会时常出现,包括编译期间错误和运行期间的错误。编译期间的错误编译器会帮助我们一起修正,但是运行期间的错误编译器就无能为力了。如果程序在运行期间出了错误我们置之不理,程序就会终止或者直接导致系统崩溃,后果还是很严重的。那么,对运行期间出现的错误我们如何处理或补救呢?java很贴心的提供了异常处理机制来处理运行期间出现的错误,异常处理机制可以帮助我们更好的提升程序的健壮性。

下面我们来看下java中异常的分类:

 

在java中Throwable是所有异常的父类,Error类是error类型异常的父类,Exception是exception类型异常的父类,RuntimeException类是所有运行时异常的父类RuntimeException以外的且继承Exception的类是非运行时异常。

了解了什么是异常后,那么我们如何处理异常?

在java中如果需要处理异常,必须先对异常进行捕获,然后再对异常情况进行处理。如何对可能发生的异常代码进行异常捕获和处理呢?使用 try catch关键字即可。

一个栗子:

public static void main(String[] args) {
	try {
		File file = new File("d:/a.txt");
		if(!file.exists()){
			file.createNewFile();
		}
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

被try包含的代码说明这段代码可能会发生异常,一旦发生异常,异常便会被catch捕获到,然后需要在catch块中进行异常处理。

这是一种处理方式。在java中还提供了另外一种异常处理方式 即 抛出异常。顾名思义,也就是说一旦发生异常,我就把这个异常抛出去,让调用者去处理,自己不进行具体处理,此时需要用到throw和throws关键字。

一个栗子:

public class Test02 {
	public static void main(String[] args) {
		try {
			createFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	public static void createFile() throws IOException{
		File file = new File("d:/b.txt");
		if(!file.exists()){
			file.createNewFile();
		}
	}
}

这段代码和上段代码的区别是,在实际的createFile方法中并没有捕获异常,而是使用throws关键字声明抛出异常,即告知这个方法的调用者此方法可能会抛出IOException异常,那么在main方法中调用createFile方法的时候,采用了try...catch块进行了异常捕获处理。

当然还可以使用throw关键字手动抛出异常对象,一个栗子:

public class Test03 {
	public static void main(String[] args) {
		try {
			int[] data = new int[]{1,2,3};
			getDataByIndex(-1,data);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	public static int getDataByIndex(int index,int[] data){
		if(index <0 || index >data.length){
			throw new ArrayIndexOutOfBoundsException("数组下标越界异常");
		}
		return data[index];
	}
}

通过这三段代码,我们知道java中异常处理的话,有三种方式:

1)对代码块使用try...catch进行异常捕获处理;

2)在该代码的方法体外使用throws进行抛出声明,告知此方法的调用者这段代码可能会出现这些异常,需谨慎处理。此时有两种情况:

  如果声明抛出的异常是运行时异常,调用者可以选择性的进行异常捕获处理;

  如果声明抛出的异常是非运行时异常,调用者必须显式的使用try...catch进行捕获或者继续向上层抛出异常;

3)在代码块用throw手动抛出一个异常,此时也有两种情况,与2)类似:

  如果抛出的异常对象是运行时异常,调用者可以选择性的进行异常捕获处理;

  如果抛出的异常对象是非运行时异常,调用者必须显式的使用try...catch进行捕获或者继续向上层抛出异常。

注意:如果最终将方法抛给main方法,则相当于交给JVM自动处理,此时JVM会简单的打印异常信息。

 

关于 try,catch,finally,throw,throws 这五个关键字

1、try,catch,finally

try关键字用来包围可能会出现异常的逻辑代码,它无法单独使用,必须搭配catch,finally使用。java编译器允许的组合形式有如下三种:

try...catch...;  try...finally...;  try...catch...finally...;

注意:

1)try块只能有一个,catch块可以有多个,finally块最多只能有一个;

2)三个块的执行顺序 try-->catch-->finally;

3)如果没有发生异常,catch块不会被执行;但finally块无论在什么情况下都是会被执行的(释放资源一般放在finally块中);

4)有多个catch块的情况下,是按照catch块的先后顺序进行匹配的,一旦异常被一个catch块匹配,则不会与后续的catch块匹配;

5)有finally块的情况下,千万不要在finally块中使用return,因为finally块中的return会覆盖已有的返回值。

一个栗子:

public class Test04 {
	public static void main(String[] args) {
		String str = new Test04().openFile();
		System.out.println(str);
	}
	
	public String openFile(){
		try {
			FileInputStream inputStream = new FileInputStream("d:/a.txt");
			int ch = inputStream.read();
			System.out.println("aaa");
			return "step1";
		} catch (FileNotFoundException e) {
			System.out.println("file not found");
			return "step2";
		} catch (IOException e) {
			System.out.println("io exception");
			return "step3";
		}finally{
			System.out.println("finally block");
			//return "finally";
		}
	}
}

 控制台输出:

file not found
finally block
step2

可以看出,在try块中发生FileNotException之后,就跳到了第一个catch块,打印"file not found"信息,并将"step2"赋值给返回值,然后执行finally块,最后将返回值返回。

如果我们将finally块中return语句的注释释放开,会发生什么呢?

控制台输出:

file not found
finally block
finally

最后打印的是"finally",返回值被重新覆盖了。

所以如果方法有返回值,切记不要在finally里面写return语句。

2、throw和throws

1)throws出现在方法声明中,表示该方法可能会抛出异常,然后交给上层调用它的方法进行处理,允许throws后面跟着多个异常类型;

2)throw一般用于 在程序出现某种逻辑时,程序员主动抛出某种特定类型的异常。throw只会出现在方法体中,当方法在执行过程中遇到异常情况时,将异常信息封装为异常对象,然后throw出去。throw关键字的一个非常重要的作用就是异常类型的转换。

throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。两者都是消极处理异常的方式(并不是说不好),只是抛出或者可能抛出异常,当时不会由方法去处理异常,真正的处理异常由调用此方法的上层方法处理。

 

在类继承的时候,子类重写父类的方法,如何进行异常抛出声明?

遵循三点原则:

1)父类的方法没有声明异常,子类在重写该方法时不能声明异常;

2)如果父类的方法声明一个异常exception1,则子类在重写该方法时声明的异常不能是exception1的父类;

3)如果父类方法声明的异常类型只有运行时异常,则子类在重写该方法时也只能有运行时异常,不能有非运行时异常。

如图:

 

异常处理和设计的几个建议

1)谨慎的使用异常,不要使用异常去控制程序的流程;

  异常捕获的代价非常高昂,过多的使用异常会严重影响程序的性能。如果在程序中能够使用if语句或Boolean变量来进行逻辑判断,那么尽量减少异常的使用。

一个栗子:

public void useExceptionsForFlowControl() {   

  try {   

  while (true) {   

    increaseCount();   

    }   

  } catch (MaximumCountReachedException ex) {   

  }   

  //Continue execution   

}   

public void increaseCount() throws MaximumCountReachedException {   

  if (count >= 5000)   

    throw new MaximumCountReachedException();   

}

栗子中的useExceptionsForFlowControl()用一个无限循环来增加count直到抛出异常,这种做法并没有让代码不易读,但是却降低了程序的执行效率。

2)切忌使用空catch块

  在捕获异常之后什么都不做,相当于忽略了这个异常,空catch块意味着你的程序中隐藏了错误和异常,可能会导致程序出现不可控的结果。如果你非常确定捕获到的异常不会对程序造成影响,可以使用log日志记录,以便后续的更新和维护。

3)检查异常和非检查异常

  尽量避免使用检查异常,或者将检查异常转变为非检查异常交给上层处理。

4)注意catch块的顺序

5)不要将提供给用户看的信息放在异常信息里

  比较好的方式是将所有错误信息放在一个配置文件中统一管理。

6)避免多次在日志信息中记录同一个异常

  最好只在异常最开始发生的地方进行日志信息记录。

7)异常处理尽量放在高层进行

8)在finally中释放资源

 

参考博主Matrix海 子 https://www.cnblogs.com/dolphin0520/p/3769804.html

 

转载于:https://www.cnblogs.com/Rain1203/p/10768908.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30481087/article/details/98957223

智能推荐

openssl-3.0.0-alpha9编译_all lines in c:/openssl-3.0.9/openssl-3.0.9/extern-程序员宅基地

文章浏览阅读3.5k次。这个通讯传输加密工具,非常厉害。configure 如下之后make和make install就可以了。多谢,亲爱的美美。_all lines in c:/openssl-3.0.9/openssl-3.0.9/external/perl/modules.txt must b

python 写入csv文件固定列_python对csv文件追加写入列的方法-程序员宅基地

文章浏览阅读3.4k次。python对csv文件追加写入列,具体内容如下所示:原始数据[外链图片转存失败(img-zQSQWAyQ-1563597916666)(C:UsersinnduceAppDataRoamingTyporatypora-user-images1557663419920.png)]import pandas as pdimport numpy as npdata = pd.read_csv(r'平均..._numpy写入csv文件一列

2018年世界计算机超算大赛,在世界大学生超级计算机竞赛(ASC18)总决赛中 青海大学超算团队成功获得ASC竞赛全球一等奖...-程序员宅基地

文章浏览阅读216次。5月9日晚,2018ASC世界大学生超级计算机竞赛(ASC18)总决赛在南昌大学落下帷幕,清华大学成功卫冕总冠军,上海科技大学揽获亚军和e Prize计算挑战奖两项大奖,台湾清华大学获得最高计算性能奖。青海大学在此次比赛中取得了突破性的成绩,HPL基准测试性能仅次于台湾清华大学,HPCG性能仅次于清华大学,最终获全球一等奖,展现出优秀的超算系统与应用理解能力以及出色的性能优化能力。ASC18由亚洲..._青海大学超级计算机

asp webForm 三层框架的简单实例(一)未完待续--_asp net web form应用 三层架构部署-程序员宅基地

文章浏览阅读1.1w次,点赞8次,收藏23次。本文通过一个简单的登录实例,介绍了基本的WebForm开发方式的MVC三层框架方式。本文,是个人作为一个初学者,对webform三层框架的总结,配有相应的源代码,希望对同样迷惑的你有所帮助,如果有不对之处敬请批评指导。_asp net web form应用 三层架构部署

人脸比对(1:N)_1:n人脸检索 学术-程序员宅基地

文章浏览阅读2.9w次,点赞12次,收藏81次。第1章 前言设计出人脸1:N,随着N的增大准确率降低最小的解决方案具有很强的现实意义。人脸1:N的框架大致分为:人脸检测、人脸对齐、人脸映射与人脸识别LOSS的设计,结构如下图所示:图1:人脸1:N的主要框架人脸1:N在学术界有着广泛的研究,对于人脸检测与人脸对齐(MTCNN、TCDCN等)在业界已经有较好的效果,目前的主要性能提升有:DeepFace、DeepID,框架为CNN ..._1:n人脸检索 学术

java语言当中的标识符_java语言的标识符-程序员宅基地

文章浏览阅读458次。关于java语言当中的标识符1、什么是标识符?- 在java源程序当中凡是程序员有权利自己命名的单词都是标识符-标识符可以表示什么元素?*类名*方法名*变量名*接口名*常量名......2、标识符命名规则?【不按照这个规则来,编译器会报错,这是语法】*只能由“数字、字母、下划线_、美元符号$”组成,不能含有其他符号*不能数字开头*严格区分大小写*关键字无长度限制,但是最好不要太长3、标识符命名规范?【只是一种规范,不属于语法,不遵守规范编译器不会报_java语言的标识符

随便推点

直接插入排序——华农oj 8638_数组插入排序 oj-程序员宅基地

文章浏览阅读1.1k次。8638 直接插入排序时间限制:1000MS 代码长度限制:10KB提交次数:2050 通过次数:1393题型: 编程题 语言: G++;GCCDescription用函数实现直接插入排序,并输出每趟排序的结果.输入格式第一行:键盘输入待排序关键的个数n第二行:输入n个待排序关键字,用空格分隔数据输出格式每行输出一趟排序结果,数据之间用一个空格分隔输入样例105 4..._数组插入排序 oj

vue element-ui 表格的分页功能_elementui table 分页-程序员宅基地

文章浏览阅读3.5k次,点赞3次,收藏7次。vue element-ui 表格的分页功能_elementui table 分页

用OpenInventor实现的NeHe OpenGL教程-第三十课-程序员宅基地

文章浏览阅读65次。用OpenInventor实现的NeHe OpenGL教程-第三十课 NeHe教程在这节课介绍了碰撞检测。碰撞检测是一种比较复杂的技术。NeHe教程只是检测平面、球体、圆柱体等这些规则物体之间的碰撞检测。OpenInventor提供了任意形状物体之间的碰撞检测,当然这样的碰撞检测需要更多的计算时间。碰撞检测的算法在NeHe的教程中已经做了详尽的解释,我们就不再赘述了。程序的..._openinventor 火焰效果

视频播放加密功能的演示_视频分段加密播放实现-程序员宅基地

文章浏览阅读1.3k次。视频播放密码/设定观看密码功能,对视频文件设置观看权限,划分学员和游客,学员输入正确的密码即可观看视频。_视频分段加密播放实现

vue中用computed简单实现数据的双向绑定(getter 和 setter)_vue computed绑定表单值-程序员宅基地

文章浏览阅读6.2k次,点赞3次,收藏9次。vue是号称实现了数据双向绑定的框架,但事实上在日常开发中我们用的最多的就是 v-model 将data(vue实例中)里面的是数据和view 相关联,实现 data 更新,view自动刷新的效果。但是,在移动成都上来说,这种数据双向绑定的效果并不是特别的明显。今天,我用输入框和 computed 配置来实现一个比较明显的数据双向绑定的效果:先来看一下最终的效果:主要实现的效果:..._vue computed绑定表单值

联想微型计算机C470拆装,联想C470一体机一键U盘重装系统教程图解-程序员宅基地

文章浏览阅读3.7k次。联想C470一体机造型小巧,外观唯美时尚,易于摆放并能脱离冗杂线缆的束缚。该机是一款非常时尚的家用一体电脑,采用21.5英寸触控屏幕,全高清显示相当精细。无论是学习办公,还是家庭娱乐都能够满足用户的需求。下面给大家介绍联想C470一体机一键U盘重装系统教程图解,教大家一体机怎么装系统。相关推荐:联想C470一体机怎么进入bios设置u盘启动准备一个u盘,再下载U盘装机大师启动盘制作工具,把其做成U..._联想c470一体机拆机图解

推荐文章

热门文章

相关标签