JavaSE 异常详细解释.docx
- 文档编号:11619215
- 上传时间:2023-03-28
- 格式:DOCX
- 页数:19
- 大小:322.57KB
JavaSE 异常详细解释.docx
《JavaSE 异常详细解释.docx》由会员分享,可在线阅读,更多相关《JavaSE 异常详细解释.docx(19页珍藏版)》请在冰豆网上搜索。
JavaSE异常详细解释
JavaSE6thday
——Exception
1、本次课程知识点
1、认识异常及异常的默认处理操作;
2、异常处理语句的使用;
3、throw和throws关键字的作用;
4、异常处理的标准操作格式;
5、自定义异常和assert关键字的使用。
2、具体内容
2.1认识异常(理解)
异常是导致程序中断执行的一种指令流,即:
程序之中一旦产生了异常之后,程序在默认情况下将中断执行。
范例:
观察如下的程序:
publicclassDemo{
publicstaticvoidmain(Stringargs[]){
intx=10;
inty=0;
System.out.println("========Startofthecalculation========");
intresult=x/y;
System.out.println("Resultofthecalculation:
"+result);
System.out.println("========Endofthecalculation========");
}
}
此时,由于被除数是0,所以现在程序运行之后的结果是:
现在很明显,是在异常出现之后的语句都不再执行了,通过程序可以发现,异常出现之后,程序将导致运行,即中断执行了。
额外:
计算机的两大杀手
对于计算机而言,最导致的两个操作:
断电、除以0;
2.2异常处理语法(重点)
如果现在希望发生异常之后,程序依然可以正确的执行完毕,则可以采用如下的异常处理格式完成:
try{
//可能出现异常的语句
}[catch(异常类异常类对象){
//异常的处理
}[catch(异常类异常类对象){
//异常的处理
}[catch(异常类异常类对象){
//异常的处理
}……]]]
[finally{
//不管是否有异常都要执行此代码
}]
范例:
使用try……catch处理异常
publicclassDemo{
publicstaticvoidmain(Stringargs[]){
intx=10;
inty=0;
System.out.println("========Startofthecalculation========");
try{
intresult=x/y;
System.out.println("Resultofthecalculation:
"+result);
}catch(ArithmeticExceptione){//此处捕获的是算术异常
System.out.println(e);
}
System.out.println("========Endofthecalculation========");
}
}
此时程序的输出:
==================Startofthecalculation==================
java.lang.ArithmeticException:
/byzero
==================Endofthecalculation==================
通过输出可以发现,现在的程序可以正常的执行完毕了,而且可以发现,在try语句之中,捕获异常之后,异常代码之后的语句将不再执行了,如果现在没有异常发生,则不再执行catch语句中的操作。
现在的异常输出直接采用了输出异常对象的方式完成,而这种异常的信息并不是完整的,所以很多时候都会直接调用异常类中的printStackTrace()方法打印异常信息;
publicclassDemo{
publicstaticvoidmain(Stringargs[]){
intx=10;
inty=1;
System.out.println("========Startofthecalculation========");
try{
intresult=x/y;
System.out.println("Resultofthecalculation:
"+result);
}catch(ArithmeticExceptione){//此处捕获的是算术异常
ae.printStackTrace();//直接输出对象
}finally{//异常的出口
System.out.println("ExecutetheprocedurethoughtheException!
");
}
System.out.println("========Endofthecalculation========");
}
}
========Startofthecalculation========
Resultofthecalculation:
10
ExecutetheprocedurethoughtheException!
========Endofthecalculation========
但是写到这里也有一个问题了,抛开异常处理程序不谈,可以发现最后的输出语句也是无论是否有异常都会执行,实际上对于finally程序有特定的使用语法,而且是要结合之后的异常处理的标准格式来讲的。
但是随着java的发展,除了以上的两种格式之外,也存在了另外一种格式:
publicclassDemo{
publicstaticvoidmain(Stringargs[]){
intx=10;
inty=1;
System.out.println("========Startofthecalculation========");
try{
intresult=x/y;
System.out.println("Resultofthecalculation:
"+result);
}finally{//异常的出口
System.out.println("ExecutetheprocedurethoughtheException!
");
}
System.out.println("========Endofthecalculation========");
}
}
即在原来的基础上删掉了catch关键字,但这种写法建议绝对不要使用!
在之前的程序之中,已经进行一个异常的处理,如果现在要把程序扩充一下,例如:
现在希望两个计算的数字可以由初始化参数指定,所以现在的代码修改如下:
publicclassDemo{
publicstaticvoidmain(Stringargs[]){
intx=0;
inty=0;
System.out.println("========Startofthecalculation========");
try{
x=Integer.parseInt(args[0]);//接收第一个数字
y=Integer.parseInt(args[1]);//接收第二个数字
intresult=x/y;
System.out.println("Resultofthecalculation:
"+result);
}catch(ArithmeticExceptione){//此处捕获的是算术异常
e.printStackTrace();//直接输出对象
}finally{//异常的出口
System.out.println("ExecutetheprocedurethoughtheException!
");
}
System.out.println("========Endofthecalculation========");
}
}
但是此时一些新的问题也来了:
●问题一:
如果用户在执行程序的时候没有输入参数:
●问题二:
如果用户输入的参数不是数字:
●问题三:
输入的除数是0:
通过以上的程序分析可以发现,每种异常都应该有每种异常的类型,而之前的程序所有的异常都只按照了一种异常处理,那么这之外的异常就无法处理了,所以此时可以在try语句后增加多个catch。
publicclassDemo{
publicstaticvoidmain(Stringargs[]){
intx=0;
inty=0;
System.out.println("========Startofthecalculation========");
try{
x=Integer.parseInt(args[0]);//接收第一个数字
y=Integer.parseInt(args[1]);//接收第二个数字
intresult=x/y;
System.out.println("Resultofthecalculation:
"+result);
}catch(ArithmeticExceptione){//此处捕获的是算术异常
e.printStackTrace();//直接输出对象
}catch(ArrayIndexOutOfBoundsExceptione){
e.printStackTrace();
}catch(NumberFormatExceptione){
e.printStackTrace();
}finally{//异常的出口
System.out.println("ExecutetheprocedurethoughtheException!
");
}
System.out.println("========Endofthecalculation========");
}
}
现在程序之中可以处理三个异常,但是程序写到这个地方一个问题就该出现了,以上所有的异常都是一个个实验出来的,那么并没有感觉到异常处理的方便,如果现在是一段不熟悉的代码,你有可能花那么多的时间进行分析吗?
2.3异常的处理流程(核心)
如果现在要想简化异常的处理操作,那么就必须首先掌握异常的两大内容:
继承结构、处理流程;
以“ArithmeticException”异常类为例,观察此类的继承结构:
可以发现ArithmeticException类的父类是Throwable,表示允许抛出的,在Throwable中有两个子类:
●Error:
表示的是JVM出错,即:
程序还没有运行时所发生的错误,用户无法处理;
●Exception:
表示程序运行中发生的错误,用户可以处理;
一般情况下,所谓的异常处理异常指的是都是Exception的子类,那么按照之前所讲解的对象的转型操作而言,所有的子类对象都可以向父类自动转型,所以,那么如果现在要想简化异常的处理操作,则还要进行异常的处理流程分析。
1、在程序之中如果发生异常,则首先会有JVM自动的产生一个指定异常类的实例化对象;
2、此异常对象要被try语句所捕获,如果现在没有异常处理语句,则也交给JVM处理;
3、将此异常类的对象想方法参数传递那样,与每一个catch进行匹配,如果匹配成功,则使用catch进行处理,如果匹配不成功则向下继续匹配,如果都没有成功的则交给JVM采用默认的处理方式(程序中断);
4、当程序之中异常处理完毕之后,都会调用finally程序进行异常的出口收尾工作;
5、如果之后有其他语句,则继续执行;
通过以上的分析可以得出:
所谓的异常出来实际上还是一个引用数据类型的操作流程,
所以按照子类对象自动向父类对象转型的技术要求,则可以直接使用Exception(异常的父类)进行全部异常的处理。
如果现在希望省事,可以利用Exception进行处理,但是由于Exception的捕获范围更大,所以这种捕获必须放在捕获范围小的异常之后,否则程序在编译时就会出现错误提示。
publicclassDemo{
publicstaticvoidmain(Stringargs[]){
intx=0;
inty=0;
System.out.println("========Startofthecalculation========");
try{
x=Integer.parseInt(args[0]);//接收第一个数字
y=Integer.parseInt(args[1]);//接收第二个数字
intresult=x/y;
System.out.println("Resultofthecalculation:
"+result);
}catch(ArithmeticExceptione){//此处捕获的是算术异常
e.printStackTrace();//直接输出对象
}catch(ArrayIndexOutOfBoundsExceptione){
e.printStackTrace();
}catch(NumberFormatExceptione){
e.printStackTrace();
}catch(Exceptione){
e.printStackTrace();
}finally{//异常的出口
System.out.println("ExecutetheprocedurethoughtheException!
");
}
System.out.println("========Endofthecalculation========");
}
}
但是,Exception肯定把所有的异常都包含了,所以现在实际上以上的程序,可以采用更简便的做法:
publicclassDemo{
publicstaticvoidmain(Stringargs[]){
intx=0;
inty=0;
System.out.println("========Startofthecalculation========");
try{
x=Integer.parseInt(args[0]);//接收第一个数字
y=Integer.parseInt(args[1]);//接收第二个数字
intresult=x/y;
System.out.println("Resultofthecalculation:
"+result);
}catch(Exceptione){
e.printStackTrace();
}finally{//异常的出口
System.out.println("ExecutetheprocedurethoughtheException!
");
}
System.out.println("========Endofthecalculation========");
}
}
可是这种做法只适合于异常处理要求不高的开发环境下,如果现在开发之中要求每种异常都要分别进行处理的话,这种做法就不可取了,必须编写多个catch语句。
面试题:
1、请解释Error和Exception的求别:
●Error:
表示的是JVM出错,即:
程序还没有运行时所发生的错误,用户无法处理;
●Exception:
表示程序运行中发生的错误,用户可以处理;
2、请解释异常处理的流程:
A、在程序之中如果发生异常,则首先会有JVM自动的产生一个指定异常类的实例化对象;
B、此异常对象要被try语句所捕获,如果现在没有异常处理语句,则也交给JVM处理;
C、将此异常类的对象想方法参数传递那样,与每一个catch进行匹配,如果匹配成功,则使用catch进行处理,如果匹配不成功则向下继续匹配,如果都没有成功的则交给JVM采用默认的处理方式(程序中断);
D、当程序之中异常处理完毕之后,都会调用finally程序进行异常的出口收尾工作;
E、如果之后有其他语句,则继续执行;
2.4throws关键字(重点)
throws关键字的主要功能是在方法定义上使用的,表示一个方法之中不处理异常,而交给程序的被调用处处理,实际上就属于一种问题的转移,即:
原本是A的问题现在交给了B处理。
packagecourse_2;
classMyMath{
publicstaticintdiv(intx,inty)throwsException{//不再由方法处理
returnx/y;
}
}
publicclassDemo{
publicstaticvoidmain(Stringargs[]){
try{
System.out.println(MyMath.div(10,0));
}catch(Exceptione){
e.printStackTrace();
}
}
}
java.lang.ArithmeticException:
/byzero
atcourse_2.MyMath.div(Demo.java:
6)
atcourse_2.Demo.main(Demo.java:
13)
实际上现在在主方法之中,也可以继续向上抛出异常,直接写上throws即可。
packagecourse_2;
classMyMath{
publicstaticintdiv(intx,inty)throwsException{//不再由方法处理
returnx/y;
}
}
publicclassDemo{
publicstaticvoidmain(Stringargs[])throwsException{
MyMathm=newMyMath();
System.out.println(m.div(10,0));
}
}
java.lang.ArithmeticException:
/byzero
atcourse_2.MyMath.div(Demo.java:
5)
atcourse_2.Demo.main(Demo.java:
12)
主方法之上就是JVM了,所以如果在主方法上写了throws,则表示交给JVM进行处理(所以在程序主方法中就可以不写try……catch语句进行异常的捕获和处理了),而JVM的处理原则就是程序的中断执行,所以在开发之中,不要在main()方法上继续向上抛异常了。
2.5throw关键字(重点)
在之前的throws是在方法上定义的,而且在方法上抛出的异常也有可能就是由JVM自动抛出的,但是现在可以利用throw关键字手工的抛出一个异常。
packagecourse_2;
publicclassDemo{
publicstaticvoidmain(Stringargs[])throwsException{
try{
thrownewException("抛着玩。
");
}catch(Exceptione){
e.printStackTrace();
}
}
}
java.lang.Exception:
抛着玩。
atcourse_2.Demo.main(Demo.java:
6)
不理解,在开发之中躲异常还来不及呢,还往上招惹,不懂。
请继续看一下范例。
范例:
在方法中抛出异常。
publicclassDemo{
publicvoidthrowException()throwsException{
System.out.println("throwException()strart.");
thrownewException("Evilexception!
");
//System.out.println();//注意在抛出异常后是不能继续再写其他语句的。
}
publicstaticvoidmain(Stringargs[]){
System.out.println("MAINstrat.");
try{
newDemo().throwException();
}catch(Exceptione){
System.out.println("ReceiptedEXCEPTION!
");
e.printStackTrace();
}
System.out.println("MAINend.");
}
}
MAINstrat.
throwException()strart.
ReceiptedEXCEPTION!
java.lang.Exception:
Evilexception!
atfirstCourse.Demo.throwException(Demo.java:
6)
atfirstCourse.Demo.main(Demo.java:
13)
MAINend.
笔记:
和在main方法中抛出异常不同的是,在非main方法中抛出异常的话通常在这个方法中都会使用throwsException把所长生的异常交给调用处处理,否则自定义的throw异常就没什么意义了,如“抛着完”这个例子。
面试题:
请解释throw和throws的区别?
●throw表示人为的进行异常的抛出,手工抛出对象;
●throws是用于方法的声明上,表示一个方法不处理异常,而交给被调用处处理;
2.6异常处理的标准格式(最核心)
现在学习完了:
try……catch……finally、throw、throws等五个关键字,那么这五个关键字改如何应用呢?
下面通过一个程序的分析完成。
例如,现在要求定义一个div()方法,此方法要求在计算开始和结束的时候有信息输出,而且如果出现了异常,则要求交给被调用处处理。
packagecourse_2;
classMyMath{
publicstaticintdiv(intx,inty)throwsException{//不再由方法处理。
此处不加结果一样,因为本方法中已使用try
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JavaSE 异常详细解释 异常 详细 解释