java异常详解
2017-08-11 13:49
169 查看
在Java中异常被当做对象来处理,根类是java.lang.Throwable类,在Java中定义了很多异常类(如OutOfMemoryError、NullPointerException、IndexOutOfBoundsException等),这些异常类分为两大类:Error和Exception。
Exception分为两种,两者都在Exception类层次结构中。如下图所示:
粉红色的是受检查的异常(checked exceptions),也称为非运行时异常。
其必须被 try{}catch语句块所捕获,或者在方法签名里通过throws子句声明。受检查的异常必须在编译时被捕捉处理,命名为 Checked Exception 是因为Java编译器要进行检查,Java虚拟机也要进行检查,以确保这个规则得到遵守。
绿色的异常是非检查异常,也叫做运行时异常(runtime exceptions),需要程序员自己分析代码决定是否捕获和处理,比如 空指针,被0除…
下面的网页详细地讲解了Exception的用法及注意事项:
http://www.cnblogs.com/dolphin0520/p/3769804.html
我这里强调一下一个比较值得注意的地方:
父类和子类的函数重写情况下异常的覆盖关系:
一、父类函数如果没有声明抛出异常,那么子类可以自己抛出各种非检查异常,即运行时异常,而不能抛出检查异常。
二、如果父类函数声明抛出非检查异常,那么子类就不能抛出检查异常,但是可以抛出其他各种非检查异常;
三、上面文章说“如果父类的方法声明一个异常exception1,则子类在重写该方法的时候声明的异常不能是exception1的父类”其实是错的,例如这样就没错:
ClassCastException 是RuntimeException 的子类,程序也没出现问题。
其实这里只有检查异常才会不
9a49
允许,例如父类用EOFException,而子类用EOFException的父类IOException就会出错。
四、简而言之,其实就是函数重写跟
1. 非检查异常没关系,父类函数无论是否抛出此类型的异常,子类都可以随意声明其他非检查类型的异常。(也就是不把非检查异常当一回事,就像一对父子的名字,俩人谁要申明抛什么非检查异常并没有限制,要声明什么就声明什么)
2. 而检查异常就不一样了,子类函数声明的检查异常,父类也一定要声明,而且父类的异常还要跟子类的相同,或者是子类声明异常的父类。(检查异常要求就比较严格了,就像姓氏,父类必须为子类负责,限制了子类这方面的异常,就是父亲说我姓张,儿子也要姓张吧不能让儿子声明其他的姓。)
那究竟平时编程用什么类型的异常好:
《Effective Java》中给出的建议是: 对于可以恢复的条件使用被检查异常,对于程序错误使用运行时异常。
因为可以恢复的情况下,用检查异常可以强制别人得去处理这个异常使得程序继续。
而程序错误运行那就不必了,因为即使强制别人处理程序也是出现了错误没必要继续下去,就直接用运行时异常便可。
在Java中,声明为Error的,属于严重错误,需要根据业务信息进行特殊处理,Error不需要捕捉。 Error是无法处理的异常,比如OutOfMemoryError,一般发生这种异常,JVM会选择终止程序。 因此我们编写程序时不需要关心这类异常。
Exception分为两种,两者都在Exception类层次结构中。如下图所示:
粉红色的是受检查的异常(checked exceptions),也称为非运行时异常。
其必须被 try{}catch语句块所捕获,或者在方法签名里通过throws子句声明。受检查的异常必须在编译时被捕捉处理,命名为 Checked Exception 是因为Java编译器要进行检查,Java虚拟机也要进行检查,以确保这个规则得到遵守。
绿色的异常是非检查异常,也叫做运行时异常(runtime exceptions),需要程序员自己分析代码决定是否捕获和处理,比如 空指针,被0除…
下面的网页详细地讲解了Exception的用法及注意事项:
http://www.cnblogs.com/dolphin0520/p/3769804.html
我这里强调一下一个比较值得注意的地方:
父类和子类的函数重写情况下异常的覆盖关系:
一、父类函数如果没有声明抛出异常,那么子类可以自己抛出各种非检查异常,即运行时异常,而不能抛出检查异常。
二、如果父类函数声明抛出非检查异常,那么子类就不能抛出检查异常,但是可以抛出其他各种非检查异常;
三、上面文章说“如果父类的方法声明一个异常exception1,则子类在重写该方法的时候声明的异常不能是exception1的父类”其实是错的,例如这样就没错:
public class Father { void speak() throws ClassCastException { System.out.println("Father"); } } class Son extends Father { @Override void speak() throws RuntimeException { System.out.println("Son"); } }
ClassCastException 是RuntimeException 的子类,程序也没出现问题。
其实这里只有检查异常才会不
9a49
允许,例如父类用EOFException,而子类用EOFException的父类IOException就会出错。
四、简而言之,其实就是函数重写跟
1. 非检查异常没关系,父类函数无论是否抛出此类型的异常,子类都可以随意声明其他非检查类型的异常。(也就是不把非检查异常当一回事,就像一对父子的名字,俩人谁要申明抛什么非检查异常并没有限制,要声明什么就声明什么)
2. 而检查异常就不一样了,子类函数声明的检查异常,父类也一定要声明,而且父类的异常还要跟子类的相同,或者是子类声明异常的父类。(检查异常要求就比较严格了,就像姓氏,父类必须为子类负责,限制了子类这方面的异常,就是父亲说我姓张,儿子也要姓张吧不能让儿子声明其他的姓。)
那究竟平时编程用什么类型的异常好:
《Effective Java》中给出的建议是: 对于可以恢复的条件使用被检查异常,对于程序错误使用运行时异常。
因为可以恢复的情况下,用检查异常可以强制别人得去处理这个异常使得程序继续。
而程序错误运行那就不必了,因为即使强制别人处理程序也是出现了错误没必要继续下去,就直接用运行时异常便可。
相关文章推荐
- Java中的异常和处理详解
- java(22) - 异常详解
- Java 里的异常(Exception)详解
- 详解Java中的checked异常和unchecked异常
- Java异常详解
- Java详解之——异常机制
- Java 里的异常(Exception)详解
- JAVA 异常机制详解
- Java:将异常的完整堆栈追踪信息保存到字符串中(详解)
- Java异常详解
- 通俗易懂详解java的异常处理及自定义异常类型
- Java 中的异常和处理详解
- java 异常详解及应用实例
- Java异常处理运行时异常(RuntimeException)详解及实例
- Java异常处理详解
- Java 中的异常和处理详解
- java中的异常详解
- org.hibernate.engine.internal.Versioning.increment(Versioning.java:130)异常详解
- 【JAVA集合详解】Java ConcurrentModificationException异常原因和解决方法
- java中的异常详解(1)