java异常处理--用代码说话
来源:互联网 发布:abaqus软件介绍 编辑:程序博客网 时间:2024/05/21 09:03
1.基本概念
当出现程序无法控制的外部环境问题(如:用户提供的文件不存在,文件内容损坏,网络不可用)时,java就会用异常对象描述。
2.处理
java中使用两种方式来处理异常:
1>在发生异常的地方直接处理;
2>将异常抛给调用者,让调用者处理。
3.异常分类
1>检查性异常 java.lang.Exception
检查性异常:
程序是正确的,但因为外界的环境条件不满足而引发。比如,我晚上要去吃饭,结果,去了饭馆没开门,这是我的错吗?我吃饭(就类似于程序)有错吗?没错,只是外界条件不满足,所以这就是异常。在java中,比如,程序试图打开一个远程并不存在的Socket端口,或者打开不存在的文件时,这不是程序本身的逻辑错误,而很可能是远程机器名字错误,对商业软件系统,程序开发者必须考虑并处理这个问题,java编译器强制要求,处理这类异常类,如果不捕获这些异常,程序不能被编译。
我举一个实际案例来说明问题:
</pre><pre name="code" class="java">package com.test;import java.io.FileReader;import java.net.Socket;public class test3 { public static void main(String[] args) { //检查性异常,1.打开文件 FileReader fr=new FileReader("d:\\aa.text"); //2.连接一个192.168.1.23 ip的端口号78 }}
FileReader fr=new FileReader("d:\\aa.text");这条语句会报错,
未报告的异常错误FileNotFoundException; 必须对其进行捕获或声明以便抛出
----
Socket s=new Socket("192.168.1.23", 78);
会报错:
未报告的异常错误UnknownHostException; 必须对其进行捕获或声明以便抛出----
就算你写的ip和端口都是对的,但是编译器认为你可能写错了。
所以,检查性异常就是编译器可以事先确认的异常。
2>运行期异常 java.lang.RuntimeException
运行时异常:
这意味着,程序存在bug,如:数组越界,0被除,入参不满足规范...........这类异常需要更改程序来避免。java编译器强制要求处理这类异常。
这类异常,编译通过,这一点上,编译器“并不是足够聪明”。所以,在运行的时候会出错。属于程序逻辑上出了错。一般比较难检查。
3>错误(最严重) java.lang.Error
错误:
一般很少见,也很难通过程序解决。它可能源于程序的bug,但一般更可能源于环境问题,比如,内存耗尽,错误在程序中处理,
而由运行环境处理。
java.lang.RuntimeException继承自 java.lang.Exception。
java.lang.Error和 java.lang.RuntimeException继承自java.lang.Throwable类。
但是顶层类都是java.lang.Throwable
4.异常处理:
1>try.....catch
程序运行产生异常时,将从异常的发生点中断程序,并向外抛出异常信息。
package com.test;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.net.Socket;import java.util.logging.Level;import java.util.logging.Logger;public class test3 { public static void main(String[] args) { try { //检查性异常,1.打开文件 FileReader fr=new FileReader("d:\\aa.text"); //2.连接一个192.168.12.12 ip的端口号4567 Socket s=new Socket("192.168.1.23", 78); } catch (FileNotFoundException ex) { Logger.getLogger(test3.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(test3.class.getName()).log(Level.SEVERE, null, ex); } }}
要做到最小捕获异常的原则。是在不知道,可以catch(Exception e),最大的。
捕获结果;
六月 11, 2015 9:47:34 下午 com.test.test3 main
严重: null
java.io.FileNotFoundException: d:\aa.text (设备未就绪。)
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 java.io.FileReader.<init>(FileReader.java:58)
at com.test.test3.main(test3.java:15)
因为第一个有异常,所以第二个就没机会捕获了,程序已经中断了,想要看到第二个catch的作用,那么我现在把第一个语句注释掉,再次捕获。再次修改代码!
package com.test;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.net.Socket;import java.util.logging.Level;import java.util.logging.Logger;public class test3 { public static void main(String[] args) { try { //检查性异常,1.打开文件 // FileReader fr=new FileReader("d:\\aa.text"); //2.连接一个192.168.12.12 ip的端口号4567 Socket s=new Socket("192.168.1.23", 78); System.out.println("connect success!"); } catch (FileNotFoundException ex) { Logger.getLogger(test3.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(test3.class.getName()).log(Level.SEVERE, null, ex); } System.out.println("ok"); }}运行结果:
java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at com.test.test3.main(test3.java:17)
ok
小结:再出现异常的地方,就终止执行代码,然后进入到catch,如果,你有多个catch语句,则进入匹配异常那个的catch。
2>finally
如果把finally块放在try......catch的语句后面,finally语句是不管catch语句块是否执行,一般都会执行的。
下面是非一般情况:
a.finally块中发生异常
b. 程序所在线程死亡
c.在前面的代码中有system.exit();语句
d. 关闭cpu
package com.test;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.net.Socket;import java.util.logging.Level;import java.util.logging.Logger;public class test3 { public static void main(String[] args) { FileReader fr=null; try { //检查性异常,1.打开文件 fr=new FileReader("H:\\aa.txt"); //2.连接一个192.168.12.12 ip的端口号4567 // Socket s=new Socket("192.168.1.23", 80); } catch (FileNotFoundException ex) { System.exit(-1);//finally就不会执行 Logger.getLogger(test3.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(test3.class.getName()).log(Level.SEVERE, null, ex); } finally{ System.out.println("进入finally语句块"); //这个语句块,不管有没有异常都会执行 //一般把需要关闭的资源,如文件,或者数据库的连接,开辟的一些内存等 if(fr!=null){ try { fr.close(); } catch (IOException ex) { ex.printStackTrace(); } } } System.out.println("ok"); }}
案例说明:
package com.test;import java.io.FileNotFoundException;import java.io.FileReader;import java.util.logging.Level;import java.util.logging.Logger;public class test {public static void main(String[] args) { Father father=new Father(); father.test1(); }}class Father{ private Son son=null; public Father(){ son=new Son(); } public void test1(){ System.out.println("1"); //son.test2();//现在好了,儿子没有处理的异常抛给了父亲,父亲调用了儿子的方法, //而throws语句,是抛给调用者的,所以,此时父亲有两种方法解决这个异常, //一个是也不想管这个异常,往出抛,谁调用谁来处理这个异常,那么现在再 //往上抛就是JVM了,那好了, 既然是当父亲的,那么就管管吧,用try catch //用throws的缺点就是,不知道异常出在了哪里 try { son.test2(); } catch (FileNotFoundException ex) { System.out.println("父亲在处理异常。"); ex.printStackTrace(); } }}class Son{ public void test2() throws FileNotFoundException{ FileReader fr=null; fr=new FileReader("d://aa.txt");//这个文件并不存在的 }}输出结果:
1
父亲在处理异常。
java.io.FileNotFoundException: d:\aa.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 java.io.FileReader.<init>(FileReader.java:58)
at com.test.Son.test2(test.java:37)//真正的错误的根源在这一行
at com.test.Father.test1(test.java:27)//第27行在父亲类test1方法 里面调用了,
at com.test.test.main(test.java:11)//在主方法里面调用了
如果父亲也不管,都向上抛最后抛到主方法那里去,然后呢,Jvm处理,这样子做的效率并不高,不建议。建议,哪里出问题,就在哪里try catch。
就像下面这样的代码:不建议
package com.test;import java.io.FileNotFoundException;import java.io.FileReader;import java.util.logging.Level;import java.util.logging.Logger;public class test {public static void main(String[] args) throws FileNotFoundException { Father father=new Father(); father.test1(); }}class Father{ private Son son=null; public Father(){ son=new Son(); } public void test1() throws FileNotFoundException{ System.out.println("1"); son.test2();//现在好了,儿子没有处理的异常抛给了父亲,父亲调用了儿子的方法, //而throws语句,是抛给调用者的,所以,此时父亲有两种方法解决这个异常, //一个是也不想管这个异常,往出抛,谁调用谁来处理这个异常,那么现在再 //往上抛就是JVM了,那好了, 既然是当父亲的,那么就管管吧,用try catch //用throws的缺点就是,不知道异常出在了哪里// try {// son.test2();// } catch (FileNotFoundException ex) {// System.out.println("父亲在处理异常。");// ex.printStackTrace();// } }}class Son{ public void test2() throws FileNotFoundException{ FileReader fr=null; fr=new FileReader("d://aa.txt"); }}运行结果:
1
Exception in thread "main" java.io.FileNotFoundException: d:\aa.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 java.io.FileReader.<init>(FileReader.java:58)
at com.test.Son.test2(test.java:37)
at com.test.Father.test1(test.java:21)
at com.test.test.main(test.java:11)
Java Result: 1
- java异常处理--用代码说话
- Java异常处理机制难点解惑-用代码说话
- Java反射机制---用代码说话
- IOC/DI用代码说话
- 关于Java异常处理的学习代码
- java中如何处理异常代码示例
- JAVA:正则表达式(代码说话)
- javascript基础知识(用代码来说话)
- Android HttpClient实例详解--用代码说话
- 处理异常代码
- servlet异常处理代码
- 用代码简单介绍java中的异常的捕获及处理
- 用axis2插件生成代码时出现java.lang.reflect.InvocationTargetException异常的处理
- java 重新抛出异常 相关处理结果示例代码
- 关于JAVA异常处理机制的实验代码
- Java day08 异常处理与正常代码分离 图形面积
- java中对于异常的处理,代码简单描述
- java代码模型6(异常处理格式)
- SDNU 1015.最远路径【二叉树DFS】
- NodeJS简单的网页跳转路由demo
- MVC 常见数据验证速查手册
- 600字读懂 Git
- 具有异常判断的数据库事务Sql语句
- java异常处理--用代码说话
- RFC2889转发性能测试用例设计和自动化脚本实现
- 在Spring3中使用注解(@Scheduled)创建计划任务
- IBM Bluemix云平台24小时应用开发挑战赛参赛作品详解
- C++数据在内存中的存放的三个区域全局数据区,堆和栈
- NFC 浅析(一)
- Leetcode--MaximumGap
- Linux下select, poll和epoll IO模型的详解
- 聊聊C++临时对象的析构时间点------顺便再次提醒大家谨慎使用string的c_str方法