java核心技术中使用异常机制的技巧:
1,异常处理不能代替简单的测试,异常的基本原则是只有在异常的情况下使用异常机制。
2,不要过分的细化异常
3,利用异常层级结构,寻找更加适合的子类或者自定义异常类
4不要压制异常,对应可能出现异常的方法通过throws的方式抛出
5检测错误的时候,苛刻比放任更好。
6不要羞于传递异常
『5,6条可以总结为 早抛出,晚捕获』
java异常
java 程序执行过程中的不正常情况成为异常。
java所发生的异常分为2种。error (java虚拟机无法解决的严重问题java虚拟机内部错误,资源耗尽等)和exception (其他由于编程或者偶然的外部因素,经常需要程序处理)。
/*一、异常的体系结构
java.lang.Throwable
|—–Error:错误,不编写针对性的代码进行处理
|—–Exception:异常,要求在编写程序时,就要考虑到对这些异常的处理
|—–编译时异常[受检异常]:在编译期间会出现的异常(执行javac.exe命令时,出现异常)
|—–运行时异常【非受检异常】:在运行期间出现的异常(执行java.exe命令时,出现异常)
- 当执行一个程序时,如果出现异常,那么异常之后的代码就不再执行!
error:
main(args);//java.lang.StackOverflowError;
Byte[] b = new Byte[1000*1000*600];
//java.lang.OutOfMemoryError;
@编译时异常,试图打开的文件可能不存在,必须处理。
FileInputStream fis =
new FileInputStream(new File(“hello.txt”));
// int b;
// while((b = fis.read()) != -1){
// System.out.println((char)b);
// }
// fis.close();
@常见的运行时异常
空指针异常:NullPointerExcetion
类型转换异常:ClassCastException 【多态】泛型
算术异常:ArithmeticException
数组下标越界的异常:ArrayIndexOutOfBoundsException
java中异常分类
受检异常(编译时异常) :程序必须接受检查和处理的异常
非受检异常(运行时异常):可以不检查和处理,或者致命性错误异常
异常的处理:
java通过抓抛模型处理异常
1抛:当我们执行代码的时候,一旦出现异常,就会在异常的代码处就创建一个对应的异常类的对象,并将此对象抛出。
一旦程序抛出异常,发生异常之后的代码将不会执行。
此异常类的对象,抛给方法的调用者。
(自动抛出异常,手动抛出异常)
2,抓:抓住异常类对象。
java的2中处理异常方式:
抓异常 异常处理的方式1 try-catch-finally
异常处理的方式2 throws +异常类
try{
//可能出现异常的代码
}catch(Exception1 e1) {
//处理异常方式1
}catch(Exception2 e2) {
//处理异常的方式2}…
finally{
//一定执行的代码}
try-catch-finally注意:
1【try 语句内的定义的局部变量,只在try语句的{}内有效】
2 finally 语句可选
3 catch 语句是对异常的处理,常用的方法,如下:
getMessage();printStackTrace();
也可以自己定义方法来处理异常。
4 可以有多个catch语句,try{}中抛出的异常类对象【在抛出异常对象后面的代码将不再执行】从上往下去依次匹配catch语句中的异常类的类型,一旦满足就执行catch中的代码,执行结束之后就跳过其后的多条catch语句,继续执行后续的代码。
5 如果异常处理了,之后的代码就可以正常运行了。
6 catch语句中若多个异常类型,范围小(子类范围 小于 父类范围)的异常在前面。
7 finally 语句中一定会被执行的代码,不管catch中是否有异常,以及方法是否有return语句,它都一定会被执行。
8 try catch 语句可以相互嵌套
使用 try-catch - finally 处理编译时异常,相当于将 编译时异常 转为 运行时异常。
对于运行时异常,可以不显式的处理
对于编译异常,必须要显示的处理。
抓异常,异常处理的方式二 :在方法的声明处,显示的抛出该异常对象的类,当然也可以抛出该异常类的父类。(多态)
modifier type method (arguments…) throws Exception1,Exception2 {
//body}
如果在当前方法中出现异常,会抛出一个异常类的对象,并抛给方法的调用者。
异常对象可以逐层往上抛,直至main()中,在抛的过程中可以通过try-catch-finally语句进行处理,到了main方法的时候必须处理。
对于两者处理异常的方式的使用情景:
1,如果有一些语句要一定被执行,那么就使用try-catch-finally处理。比如io流的关闭,数据库连接关闭,
2,几个方法中的异常需要统一处理,针对几个方法而言适合使用throws处理
3,如果父类被重写的方法没有抛出异常,那么子类重写的方法必须使用try-catch语句来保证他没有异常。
抛异常,一旦程序执行过程中,出现异常,就会抛出一个异常类的对象。(自动抛出异常类对象,手工抛出异常,(throw +异常类的对象)例如:
throw new RuntimeException(“xxxxxx”);//运行时异常,可以不显式的处理,只有在运行的时候才会出现。
【当然抛出的异常,可以是现成的异常类,也可以是自己创建的异常类】
手动的抛出异常,如果是运行时异常,可以不显式的处理,
但是如果是编译时异常,则必须使用如上的方式处理异常。
【如何自定义一个异常类】
1,继承现有的异常类
2,提供一个唯一的序列号属性作为静态常量。
另外提供几个重载的构造器即可。
子类重写的父类的方法抛出的异常必须要小于或者等于父类方法的异常。(小于或者等于 即使父类异常类型的子类或者其本身)
原因 (子类对象在向上转型的时候编译器此时将子类对象看作父类类型,所以try-catch语句必须要能够catch 这个异常。)