Java中异常处理.docx
- 文档编号:16719725
- 上传时间:2023-07-16
- 格式:DOCX
- 页数:13
- 大小:52.38KB
Java中异常处理.docx
《Java中异常处理.docx》由会员分享,可在线阅读,更多相关《Java中异常处理.docx(13页珍藏版)》请在冰点文库上搜索。
Java中异常处理
第13章异常课堂练习(2理论+2习题课+2上机)
【教学目标】
Ø了解异常和异常处理的概貌(第13.2节)。
Ø探究使用异常处理的优点(第13.3节)。
Ø区别异常的类型:
Error(致命的)和Exception(非致命的),以及必检和免检异常(第13.4节)。
Ø在方法头中声明异常(第13.5.1节)。
Ø在方法中抛出异常(第13.5.2节)。
Ø编写try-catch块处理异常(第13.5.3节)。
Ø解释异常是如何传播的(第13.5.3节)。
Ø在try-catch块中使用finally子句(第13.6节)。
Ø只为非预期错误使用异常(第13.7节)。
Ø在catch块中重新抛出异常(第13.8节)。
Ø创建链式异常(第13.9节)。
Ø定义自定制的异常类(第13.10节)。
【教学重点】
Ø了解异常的处理机制
Ø异常的解决方法
ØException类的作用及其使用方法
Ø必检异常、免检异常的特点
【基本知识点】
1、常见异常演示
(1)算数异常:
java.lang.ArithmeticException
在算术运算中,0作为除数时,系统将产生该异常,示例:
publicstaticvoidmain(String[]args){
intx=10;
inty=0;
intm=x/y;
}
Exceptioninthread"main"java.lang.ArithmeticException:
/byzero
atexception.NotChecketException.main(NotChecketException.java:
7)
(2)数组越界异常:
java.lang.ArrayIndexOutOfBoundsException
在数组下标越界时,将产生该异常,示例:
publicstaticvoidmain(String[]args){
intarr[]={1,2,3};
System.out.println(arr[3]);
}
Exceptioninthread"main"java.lang.ArrayIndexOutOfBoundsException:
3
atexception.NotChecketException.main(NotChecketException.java:
6)
(3)数组存储异常:
java.lang.ArrayStoreException
在数组中存入与之声明类型不符的类型,将产生该异常,示例:
publicstaticvoidmain(String[]args){
boolean[]b={false,true,false};
intattr[]={1,2,3};
System.arraycopy(attr,0,b,0,1);
}
Exceptioninthread"main"java.lang.ArrayStoreException
atjava.lang.System.arraycopy(NativeMethod)
atexception.NotChecketException.main(NotChecketException.java:
7)
(4)对象转换异常:
java.lang.ClassCastException
将对象A转换成为对象B时,如果A既不是与B同一个类,也不是B的子类,将产生该异常,示例:
publicstaticvoidmain(String[]args){
Objectobj=newObject();
intin[]=(int[])obj;
}
Exceptioninthread"main"java.lang.ClassCastException:
java.lang.Objectcannotbecastto[I
atexception.NotChecketException.main(NotChecketException.java:
6)
(5)空指针异常:
java.lang.NullPointerException
引用空对象的实例或方法时,将产生该异常。
示例:
publicstaticvoidmain(String[]args){
Stringstr=null;
System.out.println(str.length());
}
Exceptioninthread"main"java.lang.NullPointerException
atexception.NotChecketException.main(NotChecketException.java:
6)
2、try…catch语句捕获异常
publicclassExceptionDemo1{
publicstaticvoidmain(String[]args){
inti[]={1,2,3};
try{
System.out.println("i[0]="+i[0]);
System.out.println("i[3]="+i[3]);
}catch(ArrayIndexOutOfBoundsExceptione){
System.out.println("出现异常"+e.getMessage());
}
System.out.println("i[1]="+i[1]);
}
}
i[0]=1
出现异常3
i[1]=2
以上面的程序运行结果可以发现,在程序中加入异常处理代码后,当异常发生时,整个程序没有因为异常的出现而中断执行。
3、try…catch…finally语句捕获异常
publicclassExceptionDemo4{
publicstaticvoidmain(String[]args){
inti[]={1,2,3};
try{
System.out.println("i[0]="+i[0]);
System.out.println("i[3]="+i[3]);
}catch(ArrayIndexOutOfBoundsExceptione){
System.out.println("出现异常"+e.getMessage());
}finally{
System.out.println("......无论是否有异常,都会执行finally语句......");
}
System.out.println("i[1]="+i[1]);
}
}
i[0]=1
出现异常3
......无论是否有异常,都会执行finally语句......
i[1]=2
其中,不论try代码块中发生了哪种异常,也不论try代码块和catch代码块是否可以正常执行,finally代码块都保证会执行。
即使前面的try…catch代码块都无法捕获这个异常,或者在catch代码块中还有其他异常产生,在将新的异常传递给java运行时环境之前都会先执行finally代码块。
4、多个catch代码块
publicclassExceptionDemo5{
publicstaticvoidmain(String[]args){
FileReaderfr=null;
try{
fr=newFileReader("test.txt");
fr.read();
}catch(FileNotFoundExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}finally{
try{
fr.close();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
}
使用多个catch语句块的时候,请注意catch代码块的排顺序问题。
Catch代码块捕获异常是按照顺序的,如果前面已经有一个异常类型被捕获了,但又同时满足后面的异常类型时,就不会被捕获了。
5、在调用方法出处理被抛出的异常
publicclassException6{
publicstaticvoidarrException()throwsIOException{
FileReaderfr=newFileReader("不存在的文档.txt");
fr.close();
}
publicstaticvoidmain(String[]args){
try{
arrException();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
在上面的程序中,“不存在的文档”表示在同一个目录下没有该文档。
当arrException()方法产生了异常,此方法并不作处理,而是交由调用arrException()方法的main方法处理。
6、错误的使用throws
在上面的程序中,arrException()方法抛出的异常类型为Exception。
比调用arrException()方法的main方法能处理的异常范围大,所以编译错误。
7、主方法main使用throws关键字
publicclassExceptionDemo8{
publicstaticvoidarrException()throwsException{
FileReaderfr=newFileReader("不存在的文档.txt");
fr.close();
}
publicstaticvoidmain(String[]args)throwsException{
arrException();
}
}
Exceptioninthread"main"java.io.FileNotFoundException:
不存在的文档.txt(Nosuchfileordirectory)
atjava.io.FileInputStream.open(NativeMethod)
atjava.io.FileInputStream.
146)
atjava.io.FileInputStream.
101)
atjava.io.FileReader.
58)
atexception.ExceptionDemo8.arrException(ExceptionDemo8.java:
8)
atexception.ExceptionDemo8.main(ExceptionDemo8.java:
12)
8、若需要在程序中自行抛出异常,可以使用throw关键字。
Throw语句可以单独使用,用于方法体内部,throw抛出的是异常类的实例。
如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型,该方法的调用者也必须检查处理抛出的异常。
如果抛出的而是Error或RuntimeException,则该方法的调用者可选择是否处理该异常。
示例:
自行抛出免检异常
publicclassExceptionDemo9{
publicstaticvoidarrException(){
thrownewNullPointerException("自行抛出的免检异常--空指针异常");
}
publicstaticvoidmain(String[]args){
try{
arrException();
}catch(NullPointerExceptione){
e.printStackTrace();
}
}
}
自行抛出检查异常
publicclassExceptionDemo10{
publicstaticvoidarrException()throwsIOException{
thrownewIOException("自行抛出的免检异常--IO异常");
}
publicstaticvoidmain(String[]args){
try{
arrException();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
上述两个程序产生的异常对象都是自行抛出的,它们的区别是,使用throw关键字抛出免检异常时,不需要在方法头部声明方法可能抛出的异常类型。
而抛出的是检查异常时。
必须在方法头部声明方法可能抛出的异常类型。
9、catch和throw同时使用
publicclassExceptionDemo12{
publicstaticvoidarrException(int[]arr){
try{
intm=arr[2]/arr[0];
System.out.println(arr[2]+"/"+arr[0]+"="+m);
}catch(ArithmeticExceptione){
e.printStackTrace();
thrownewArithmeticException("被除数不能为0");
}
}
publicstaticvoidmain(String[]args){
Scannersc=newScanner(System.in);
intarr[]=newint[5];
try{
for(inti=0;i System.out.println("第"+(i+1)+"个元素: "); arr[i]=sc.nextInt(); } arrException(arr); }catch(Exceptione){ e.printStackTrace(); } } } 在上面的程序中,当arrException()中的catch代码块捕获到异常时,系统会打印该异常的信息。 并抛出一个ArithmeticException类型的异常,交由调用arrException()方法的main方法处理这个ArithmeticException 10、.try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行 publicclassExceptionDemo11{ publicstaticvoidmain(String[]args){ System.out.println(newExceptionDemo11().test()); } staticinttest(){ intx=1; try{ returnx; }finally{ ++x; } } } ---------执行结果--------- 1 运行结果是1,为什么呢? 主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。 11、 publicclassSmallT{ publicstaticvoidmain(Stringargs[]){ SmallTt=newSmallT(); intb=t.get(); System.out.println(b); } publicintget(){ try{ return1; }finally{ return2; } } } 返回的结果是2。 可以通过下面一个例子程序来解释这个答案,从下面例子的运行结果中可以发现,try中的return语句调用的函数先于finally中调用的函数执行,也就是说return语句先执行,finally语句后执行,所以,返回的结果是2。 Return并不是让函数马上返回,而是return语句执行后,将把返回结果放置进函数栈中,此时函数并不是马上返回,它要执行finally语句后才真正开始返回。 publicclassTest{ publicstaticvoidmain(String[]args){ System.out.println(newTest().test()); } inttest(){ try{ returnfunc1(); }finally{ returnfunc2(); } } intfunc1(){ System.out.println("func1"); return1; } intfunc2(){ System.out.println("func2"); return2; } } func1 func2 2 结论: finally中的代码比return和break语句后执行 【可选知识点】 1、异常处理对性能的影响 一般而言,在java程序中使用try…catch…finally语句,不会对程序的性能造成很大的影响,仅仅当异常发生时,java虚拟机才需要执行额外的操作,来定位处理异常的代码块,这时会对性能产生负面影响。 如果抛出异常的代码了块和捕获异常的代码块位于同一个方法中,这种影响就会小一些;如果java虚拟机必须搜索方法调用栈来寻找异常处理代码块,对性能的影响就比较大了。 尤其当异常处理代码块位于调用栈的底部时,java虚拟机定位异常处理代码块就需要大量的工作。 2、重写方法时遇到异常应该注意的地方 重写方法异常时,可以抛出与被重写方法相同的异常或被重写方法异常的子类异常。 如果父类方法没有声明抛出异常,那么子类重写方法不可以声明抛出检查异常,但可以声明抛出免检异常。 如果父类的方法抛出遗产共包括自定义异常,那么子类覆盖方法可以不声明抛出异常。 但是,如果子类重写方法要抛出异常的话,只能抛出与被重写方法相同的异常或被重写方法异常的子类,不能是其他的检查异常。 3、自定义异常 【作业安排】 【教学提示】
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 异常 处理