1.异常的概念
在程序运行时,打断正常程序流程的不正常情况分两类:
1.错误(Error):应用程序无法捕获的严重问题(自己无法处理)
例:
虚拟机相关的问题,如虚拟机崩溃、动态链接失败、低层资源错误等
总是不受编译器检查的(Unchecked)
可以被抛出,但无法恢复,不可能被捕获
2.异常(Exception):应用程序可捕获的一般问题(自己可以处理)
例:
试图打开的文件不存在
网络连接中断
数组越界
要加载的类找不到
……
异常的分类:
- Runtime异常(免检异常)–经常出现的异常但没必要花大量精力去处理(不可捕获):由Runtime异常类(继承Exception类)及其子类表示的异常,如数组越界、算术运算异常、空指针异常等。
- 必检异常–不经常出现但影响力很大(可捕获):除Runtime异常类及其子类之外的所有异常,如文件不存在、无效URL等。
public class TestEx {public static void main(String[] args) {int [] array = {1,2,3};//System.out.println(array[3]);//抛出异常//Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3//at java005.TestEx.main(TestEx.java:6)//可以去帮助文档查ArrayIndexOutOfBoundsException//System.out.println(10/0);//抛出异常//Exception in thread "main" java.lang.ArithmeticException: / by zero//at java005.TestEx.main(TestEx.java:11)}
}
2.Java的异常类层次
Java.lang.Throwable是所有异常类的父类
1.检索异常的相关信息
2.输出显示异常发生位置的堆栈追踪轨迹
ArithmetcException:整数的除0操作导致的异常,如:int i=10/0;
NullPointerException:对象未实例化时,即试图通过该对象的引用访问其成员变量或方法,如Date d=null; System.out.println(d.toString());
IOException:输入/输出时可能产生的各种异常
(所有继承Exception类的子类都以Exception结尾)
3.异常处理方法
- 捕获并处理异常
- 将方法中产生的异常抛出
3.1捕获并处理异常
通过try-catch-finally语句来实现,基本格式:
try{ /** 监控区域 /
//一条或多条可能抛出异常的Java语句
}catch(ExceptionType1 e1){ /* 异常处理程序 /
//捕获到ExceptionType1类型的异常时执行的代码
}catch (ExceptionType2 e2){ /* 异常处理程序 */
//捕获到ExceptionType2类型的异常时执行的代码
} …
finally{
//执行最终清理的语句
}
try-catch-finally可以实现嵌套
举例:
try { System.out.println(10/0);System.out.println("1");System.out.println(array[3]);}catch(ArrayIndexOutOfBoundsException aioobe){System.out.println("2");}catch(ArithmeticException ae) {System.out.println("3");}finally {System.out.println("4");}System.out.println("5");
try {System.out.println(array[3]); System.out.println(10/0);System.out.println("1");}catch(ArrayIndexOutOfBoundsException aioobe){System.out.println("2");}catch(ArithmeticException ae) {System.out.println("3");}finally {System.out.println("4");}System.out.println("5");
try {System.out.println(array[3]); System.out.println(10/0);System.out.println("1");}catch(ArithmeticException ae) {System.out.println("3");}finally {System.out.println("4");}System.out.println("5");
注意:在try语句块内,只要遇到第一个异常就会执行catch语句,剩下的不再执行,finally 语句块可以省略,若finally语句块存在,则无论是否发生异常均执行
package java005;public class TestEx {public static void main(String[] args) {TestEx t = new TestEx();
//28行 t.m(0);}public void m(int n) throws ArithmeticException{if(n==0) {
//32行 ArithmeticException e = new ArithmeticException("除数不能为0");throw e;//可理解为传入到了catch(ArithmeticException ae){ae.printStackTrace();//返回堆栈路径ae.getMassage();}}}
}
3.2多种异常同时处理
FileInputStream in = null;try {in = new FileInputStream("a.txt");int b = in.read();while(b != 1) {b = in.read();System.out.println(b);}}catch (FileNotFoundException fe) {fe.printStackTrace();}catch (IOException ioe) {//IOException是FileNotFoundException的父类,catch按照从上往下的顺序运行,故子类应排在父类之前ioe.printStackTrace();}finally {try {in.close();}catch(IOException e) {e.printStackTrace();}}
封装一下
public void readMethod(String fileName) {FileInputStream in = null;try {in = new FileInputStream(fileName);int b = in.read();while(b != 1) {b = in.read();System.out.println(b);}}catch (FileNotFoundException fe) {fe.printStackTrace();}catch (IOException ioe) {//IOException是FileNotFoundException的父类,catch按照从上往下的顺序运行,故子类应排在父类之前ioe.printStackTrace();}finally {try {in.close();}catch(IOException e) {e.printStackTrace();}}}
如果不想在readMethod方法里面实现处理异常,将该异常抛出到调用该方法的程序
public void readMethod(String fileName)throws FileNotFoundException,IOException {FileInputStream in = null;in = new FileInputStream(fileName);int b = in.read();while(b != 1) {b = in.read();System.out.println(b);}}public void callRead() {try {readMethod("a.txt");}catch (FileNotFoundException fe) {fe.printStackTrace();}catch (IOException ioe) {//IOException是FileNotFoundException的父类,catch按照从上往下的顺序运行,故子类应排在父类之前ioe.printStackTrace();}}
若一个异常在转向到main()后还未被处理,则程序将非正常终止。
4.自定义异常类
public class ServerTimeOutException extends Exception{private String reason;private int port ;public ServerTimeOutException(String reason, int port){this.reason = reason;this.port = port;}public String getReason(){return reason;}public int getPort(){return port;}
}
Public void connectMe(String serverName) throws ServerTimeOutException{int success;int portToConnect = 80;success = open(serverName, portToConnect);if(success= -1){throw new ServerTimedOutException(“Couldnot connect”,80);}
}
Public void findServer(){…try{connectMe(defaultServer);} catch (ServerTimeOutException e){System.out.println(“Server timed out, try another”);}
}
4.1方法重写抛出异常
注意:重写方法需要抛出与原方法所抛出异常类型一致的异常或者不抛出异常。