标签:error 关键字 通过 虚拟 new 相关 客户 pointer 多个
在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的,比如:客户输入数据的格式,输入值的范围,读取文件是否存在,网络是否始终保持通畅等等。
对于程序设计人员需要尽可能的预知所有可能发生的情况,尽可能的保证程序能在所有最糟糕的情况下都能运行。
但实际上,意外情况是不胜枚举的,程序可能发生的异常情况远远多于程序员所能考虑到的意外情况。
Java的异常处理机制可以让程序具有良好的容错性,让程序更加健壮,当程序出现异常时,系统会自动生成一个Exception对象来通知程序,从而实现将“业务功能实现代码”和“错误处理代码”分离,使程序具有更好的可读性。
异常指的是在运行期出现的错误,在编译阶段出现的语法错误等,不能称之为异常
Java程序在运行期所发生的异常事件可分为两类:Error Exception,不包含语法错误等这些错误,下图是Java中异常类的继承关系图:
Java虚拟机无法解决的严重问题。如:JVM系统内部错误,系统崩溃,动态链接失败等等,这种错误无法恢复或不可能捕获,将导致应用程序中断,通常程序无法处理这些错误,因此程序中不要试图使用catch块来捕获Error对象。一般不进行处理。
其它因程序设计错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:算数异常,空指针访问,数组下标越界,所要读取的文件不存在等等
l 主要分成两类:
l 一类是编译异常,必须处理之后才能正常编译(类找不到,IO异常...在API文档中明确写明throws...的方法,必须要进行处理)
l 一类是运行时异常RuntimeException,这种异常可以处理,也可以不处理(算数异常,空指针等)
是指编译程序不要求强制处置的异常。一般是指程序设计时的逻辑错误,是程序员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常。
对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
是指编译程序要求必须处置的异常。
Java程序必须捕获或声明所有编译时异常。
对于这类异常,如果程序不处理,可能会带来意想不到的结果,编译都不能通过
对于这些运行时异常(不是编译异常),一般有两种解决方法:
try尝试:将可能发生异常的语句放入其中
catch捕获:当try块中的异常发生时,将产生一个异常对象,拿这个对象去匹配catch块中的异常类,如果和catch中的类型匹配了,就执行这个catch块中的语句,这也就意味着,catch块可以有多个。
从以上程序可以看出,一个try后可以加多个catch块,针对try语句块中发生的异常分别捕获,当然,只能有一个catch块被执行,从执行的逻辑上看,和switch分支语句很相似。
如果把Exception类对应的异常catch块放在前面的话,一旦发生错误,将直接进入该catch块,因为所有的异常都是Exception或其子类的实例,而排在它后面的catch块将永远也不会得到执行的机会。
实际上,进行异常捕获时,不仅应该把Exception类对应的catch块放在最后,而且所有父类异常块都应该排在子类异常catch块的后面,简记为:先处理小异常(子),后处理大异常(父)。否则编译出错
如果程序需要在catch块中访问异常对象的相关信息,可以通过访问catch块后的异常形参来获得,当Java运行时决定调用某个catch块来处理该异常对象时,会将异常对象赋值给catch块后的异常参数(即:异常类型的形参),程序即可通过该参数来获得异常的相关信息。
所有的异常对象都包含了以下几个常用的方法:
import java.util.Date;
public class ErrorDemo {
public static void main(String[] args) {
Object obj = new Date();
String str = (String)obj;
}
}
@Test
public void test5(){
String str = new String("AA");
str = null;
System.out.println(str.length());
}
在API中查看方法声明后带throws关键字的
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ErrorDemo {
public static void main(String[] args) {
FileInputStream in = null;
// in = new FileInputStream("a.txt");//error,没有捕获
try{
in = new FileInputStream("a.txt");//有可能会抛出异常,必须捕获
}catch(FileNotFoundException fe){
fe.printStackTrace();
}
}
}
有的时候,在try语句块中打开了一些物理资源,如数据库连接,网络连接,磁盘文件等,这些物理资源都必须显式回收。
Java中的垃圾回收机制不会回收任何物理资源,垃圾回收机制只能回收内存中对象所占用的内存资源。
那么在哪里回收物理资源呢?能在try语句块中么?如果try块中执行某条语句出现异常的话,则该语句之后的语句都没有机会执行,这将导致其后的资源回收语句得不到执行。如果在catch块中执行资源回收的话,catch语句块也完全有可能得不到执行,这也会导致资源不能得到回收。
为了保证一定能够回收在try块中打开的物理资源,异常处理处理机制提供了finally块,不管try中的哪一条语句出现异常,也不管哪一个catch块被执行,甚至在try或者catch中执行了return语句,finally块总会被执行。完整的异常处理结构语法如下:
try{
业务处理语句
}catch(异常1 e1){
异常处理语句
}catch(异常2 e2){
异常处理语句
}
...
finally{
资源回收语句
}
11.注意:
在异常处理的结构中,只有try块是必须的,也就是说,如果没有try块,则不能有后面的catch和finally块,catch和finally两者至少出现一个,当然也可以同时出现;捕获子类异常的catch块必须位于捕获父类异常catch块的前面;finally块应该位于所有的catch块后面
12.注意事项:
通常情况下,不要在finally块中使用return或者thorw等导致方法终止的语句,(throw后面讲),一旦在finally块中使用了return或者throw语句,将会导致try块,catch块中的return,throw语句失效。
当程序在try/catch中遇到了return或者是throw语句,程序停止执行,但是并不会立即结束该方法,而是去寻找是否包含了finally块,如果没有finally块,则立即执行return或者throw语句,方法终止;如果有finally块,程序立即开始执行finally块,只有当finally块中语句执行完了,系统才会返回到try块中执行return或者是throw语句;如果finally块中也包含了return或者是throw等导致方法结束的语句,则在finally块中已经终止了方法,程序就不会再跳回去执行try块,catch块中的任何代码。换句话说,在finally中的return语句提前终止了方法。
13.提示:
尽量避免在finally块中使用return,throw等语句,会导致一些非常特别,难以察觉的错误,不利于程序开发。
标签:error 关键字 通过 虚拟 new 相关 客户 pointer 多个
原文地址:http://www.cnblogs.com/xiejiajun/p/6636186.html