异常的捕获
(1)语法格式:
try{
编写过程中可能发生异常的代码;
}
catch(异常类型 引用变量名){
编写针对该异常类的处理代码;
}
...(此处表示可能有多个catch)
finally{
编写无论是否发生异常都要执行的代码;
}
注意事项:
a、当需要编写多个catch分支时,切记要把小类型放在大类型的前面
b、也可以直接写成:
catch(Exception e){}
c、finally通常用于进行 善后处理,如:关闭已打开的文件等。
(2)异常捕获案例
FileInputStream例子(后续IO流会涉及,后续更新)
检测性异常---解决方案:进行异常的捕获
FileInputStream fis=new FileInputStream("d:/a.txt");
fis.close();
写入上述代码后会显示:Unhandled exception type FileNotFoundException
利用surround with try/catch进行异常的捕获
捕获后的代码:(要记得对fis对象赋初值null,否则会提示:The local variable fis may not have been initialized;变量未赋初始值)
FileInputStream fis=null;
try {
fis = new FileInputStream("d:/a.txt");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
可以简单的加入输出打印来观察各种情况下的代码的执行流程,如下代码所示:
// 检测性异常---解决方案:进行异常的捕获 FileInputStream fis = null; try { System.out.println("1"); //当程序执行过程中发生了异常后直奔catch分支进行处理 fis = new FileInputStream("d:/a.txt"); System.out.println("2"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block System.out.println("3"); e.printStackTrace(); System.out.println("4"); } try { System.out.println("5"); fis.close(); System.out.println("6"); } catch (IOException e) { // TODO Auto-generated catch block System.out.println("7"); e.printStackTrace(); System.out.println("8"); }catch (NullPointerException e) { e.printStackTrace(); } System.out.println("世界上最深情的相依就是你try我在catch,无论你发什么样的脾气,我都会默默承受并静静的处理,到那时再来期待我们的fianlly!"); } //当程序执行过程中没有发生异常时执行流程是:1 2 5 6 世界上... //当程序执行过程中发生异常时执行流程是:1 3 4 5 空指针异常,导致程序没有往下执行 //当程序执行过程中发生异常并且手动处理空指针异常时的执行过程:1 3 4 5 世界上....
运行结果:
1 3 java.io.FileNotFoundException: d:\a.txt (系统找不到指定的文件。) 4 5 at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.<init>(FileInputStream.java:138) at java.io.FileInputStream.<init>(FileInputStream.java:93) at day03_Exception.ExceptionText.main(ExceptionText.java:14) java.lang.NullPointerException at day03_Exception.ExceptionText.main(ExceptionText.java:25) 世界上最深情的相依就是你try我在catch,无论你发什么样的脾气,我都会默默承受并静静的处理,到那时再来期待我们的fianlly!
手动处理异常和没有处理的区别:代码是否可以继续往下执行。
(3)finally
当异常没有被手动处理时,发生异常时将会自动交给JAVA虚拟机去执行,将会打印错误消息,,并终止后续代码的执行。
案例代码:
try {
int ia=10;
int ib=0;
System.out.println(ia/ib);
} catch (ArithmeticException e) {
e.printStackTrace();
String str1=null;
System.out.println(str1.length());
}finally {
System.out.println("无论是否发生异常都要执行我~");//依然执行
}
System.out.println("over!");//不执行了
运行结果:
java.lang.ArithmeticException: / by zero
无论是否发生异常都要执行我~
at day03_Exception.ExceptionFinallyText.main(ExceptionFinallyText.java:8)
Exception in thread "main" java.lang.NullPointerException
at day03_Exception.ExceptionFinallyText.main(ExceptionFinallyText.java:12)
可能会涉及到的笔试考点:finally会把之前的return返回值进行覆盖。代码如下:
package day03_Exception;
import org.omg.CORBA.PUBLIC_MEMBER;
public class ExceptionFinallyText {
public static int test() {
try {
int[]arr=new int[5];
System.out.println(arr[5]);
return 0;
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
return 1;
}finally {
return 2;
}
}
public static void main(String[] args) {
try {
int ia = 10;
int ib = 0;
System.out.println(ia / ib);
} catch (ArithmeticException e) {
e.printStackTrace();
// String str1 = null;
// System.out.println(str1.length());
} finally {
System.out.println("无论是否发生异常都要执行我~");// 依然执行
}
System.out.println("over!");// 不执行了
System.out.println("===================");
int test=test();
System.out.println("test="+test);
}
}
运行结果:(可以看到最终的输出结果是test=2,将之前的return 1的1进行了覆盖)
无论是否发生异常都要执行我~
over!
===================
java.lang.ArithmeticException: / by zero
test=2
at day03_Exception.ExceptionFinallyText.main(ExceptionFinallyText.java:24)
java.lang.ArrayIndexOutOfBoundsException: 5
at day03_Exception.ExceptionFinallyText.test(ExceptionFinallyText.java:9)
at day03_Exception.ExceptionFinallyText.main(ExceptionFinallyText.java:35)
异常的抛出
(1)概念
在某些情况下有些异常不能处理或者不便于处理时,就可以将该异常转移给该方法的调用者,这种方法就叫做异常的抛出,当该方法执行出现异常,则底层生成一个异常类抛出,此时异常代码后续的代码就不会再执行。
语法格式:
访问权限 返回值类型 方法名称(形参列表)throws 异常类型1,异常类型2.....{方法体;}
如:
public void show() throws IOException{
}
代码案例:
public class ExceptionThrowTest { public static void show() throws IOException { FileInputStream fis =new FileInputStream("d:/a.txt"); System.out.println("看一下抛出异常后是否继续向下继续执行"); fis.close(); } public static void main(String[] args) { try { show(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
运行结果:
java.io.FileNotFoundException: d:\a.txt (系统找不到指定的文件。) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.<init>(FileInputStream.java:138) at java.io.FileInputStream.<init>(FileInputStream.java:93) at day03_Exception.ExceptionThrowTest.show(ExceptionThrowTest.java:9) at day03_Exception.ExceptionThrowTest.main(ExceptionThrowTest.java:16)
由此看出输出那行并没有执行!!!
建议不在main方法中再对异常进行抛出,因为本身JAVA虚拟机的负担就很重了,就不要再给它添加负担啦~~~
方法重写的原则:
1、要求方法名相同,参数列表相同以及返回值类型相同,从jdk1.5开始支持返回子类类型;
2、要求方法的访问权限不能变小,可以相同或者变大;
3、要求方法不能抛出更大的异常
注意:
子类重写的方法不能抛出更大的异常,不能抛出平级不一样的异常,但是可以抛出一样的异常,更小的异常以及不抛出异常。
经验分享:
1、若父类中被重写的方法没有抛出异常时,则子类中重写的方法只能进行异常的捕获处理。
2、若一个方法内部又以递进方式分别调用了好几个其他方法,则建议这些方法内可以使用抛出的方法处理到最后一层进行捕获方式处理。
示例代码:
首先是ExceptionMethod类如下所示:
public class ExceptionMethod {
public void show()throws IOException{}
}
其次是继承ExceptionMethod类的子类SubExceptionMethod类,子类SubExceptionMethod代码如下:
public class SubExceptionMethod extends ExceptionMethod{
/*
* 子类重写的方法可以抛出和父类方法中一样的异常
*/
@Override
//public void show()throws IOException{}
//子类重写的方法可以抛出更小的异常,FileNotFoundException是IOException子类
//public void show()throws FileNotFoundException{}
//public void show() {}//子类可以不抛出异常
public void show()throws ClassNotFoundException{}//不可以抛出平级不一样的异常
public void show()throws Exception{}//不可以抛出更高大的异常
}
通过上述简单的例子,可验证方法重写时的三条原则。今天先到这里啦~~~明天开启实现自定义的异常类。