一、概念
java中的异常是指在程序编译、运行中产生的异常状况,使得程序无法正常输出结果。
二、分类
按照异常出现的时间节点,可以将其分为:
(1)检查性异常:Java.lang.Exception
(2)运行期异常:Java.lang.RuntimeException
(3)错误:Java.lang.Error
以上三个类的 Java.lang.Throwable是的子孙类,其中Java.lang.Exception,Java.lang.Error是Java.lang.Throwable的子类,而Java.lang.RuntimeException则是Java.lang.Exception的子类。具体如下图
三、深入理解
检查性异常:程序的逻辑正确,但是由于外部的环境条件无法满足引发的异常。例如:I/O问题,程序试图打开一个不存在的文件,或者连接一个不存在的ip,都会报出此类错误。Java程序强制要求处理这类错误,如果不捕获这些异常,程序将无法编译。
举个例子:
import java.io.FileReader;import java.net.Socket;public class Test3 { public static void main(String[] args) { // TODO Auto-generated method stub //1.打开一个不存在的文件 FileReader fr=new FileReader("d://aa.txt"); //报错:FileNotFoundException //2.连接一个不存在的IP Socket ss = new Socket("192.168.170.55",220); //报错: IOException }}注意:此处的两个错误,不是说就一定有FileNotFound,或者没有"192.168.170.55",220 这个端口,而是说“可能存在这样的错误”,因此要抛出异常,对其处理。而且事实上我的d:/下面是有aa.txt文件的。运行期异常:是程序存在bug,例如0被除,数组越界,传入的参数不满足规范等。Java程序强制要求处理这类异常。
错误(Error):一般很少见,它可能源于程序的bug,但更可能是程序的环境问题,例如内存耗尽等,这类异常在程序中无需处理,又运行环境决定。(当然也可以尝试修改 程序启动时的初始内存大小)
四、异常的处理
1、在异常的发生地,直接 try …… catch……
看栗子1:
import java.io.FileReader;import java.io.IOException;import java.net.Socket;public class Test3 { public static void main(String[] args) { // TODO Auto-generated method stub //2.连接一个不存在的IP try { Socket ss = new Socket("192.168.170.55",220); } catch (IOException e) { // TODO Auto-generated catch block e.PRintStackTrace(); } System.out.println("OK"); }}在前面的Code中,直接对IOException进行了捕获。
输出java.net.UnknownHostException: 192.1688.170.55 at java.net.AbstractPlainSocketImpl.connect(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.SocksSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.<init>(Unknown Source) at java.net.Socket.<init>(Unknown Source) at demo.Test3.main(Test3.java:12)OK在查询后确认没有找到该主机后报出UnknownHostException() ,而且最后打印出OK。再看例子2:
public class Test3 { public static void main(String[] args) { // TODO Auto-generated method stub //1.打开一个不存在的文件 try { FileReader fr=new FileReader("d://abc.txt"); Socket ss = new Socket("192.1688.170.55",220); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch(IOException e2){ e2.printStackTrace(); } System.out.println("OK"); }}输出:java.io.FileNotFoundException: d:/abc.txt (系统找不到指定的文件。) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(Unknown Source) at java.io.FileInputStream.<init>(Unknown Source) at java.io.FileInputStream.<init>(Unknown Source) at java.io.FileReader.<init>(Unknown Source) at demo.Test3.main(Test3.java:13)OK可以看到,程序报出FileNotFoundException 之后就没有再执行 Socket ss = new Socket("192.1688.170.55",220); ,而是直接跳出了try……catch……语句,进入到了下一句!2、finally语句块
一般是把finally 语句块放在try……catch……之后,在finally 语句块中写入必须要执行的代码,相当于上了一个万能险,在catch出现异常而catch 又没有捕获时,finally将马上执行。
栗子:
public class Test3 { public static void main(String[] args) { // TODO Auto-generated method stub FileReader fr=null; //1.打开一个不存在的文件 try { fr=new FileReader("d://aa.txt"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ try { fr.close(); } catch (IOException e) { // TODO Auto-generated catch block System.out.println("在关闭文件aa.txt时出现错误!"); } } System.out.println("OK"); }}在上面的code中,加入finally语句块,fr.close 来关闭 aa文件。
而且无论前面 try ……catch……中是否出现异常,finally语句块都会执行。
注意:以下情况下finally语句块无法执行
(1)finally语句块中出现异常
(2)程序所在的线程死亡
(3)前面的代码中出现System.exit()
(4)关闭CPU
3、throws 语句
新闻热点
疑难解答