Java中异常家族介绍
上图可以简单展示一下异常类实现结构图,当然上图不是所有的异常,用户自己也可以自定义异常实现。上图已经足够帮我们解释和理解异常实现了:
1.所有的异常都是从Throwable继承而来的,是所有异常的共同祖先。
2.Throwable有两个子类,Error和Exception。其中Error是错误,对于所有的编译时期的错误以及系统错误都是通过Error抛出的。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。
3.Exception,是另外一个非常重要的异常子类。它规定的异常是程序本身可以处理的异常。异常和错误的区别是,异常是可以被处理的,而错误是没法处理的。
4.Checked Exception 可检查的异常,这是编码时非常常用的,所有checked exception都是需要在代码中处理的。它们的发生是可以预测的,正常的一种情况,可以合理的处理。比如IOException,或者一些自定义的异常。除了RuntimeException及其子类以外,都是checked exception。
5.Unchecked Exception RuntimeException及其子类都是unchecked exception。比如NPE空指针异常,除数为0的算数异常ArithmeticException等等,这种异常是运行时发生,无法预先捕捉处理的。Error也是unchecked exception,也是无法预先处理的。
异常处理
try{
//这里写可能会发生错误的代码
}catch( 这里写的是异常类型 ){
//这里写的是发生异常处理方式 通常都是打印异常
}catch( 这里写的是异常类型 ){ //catch可以写多个!
//这里写的是发生异常处理方式 通常都是打印异常
}
问题1: 如下图,为什么执行 1/0 会在控制台打印异常
public class Hello{
public static void main(String[] args) {
System.out.println(1/0);
}
}
因为main方法编译的时候 java 偷偷的给你加了个 try{} catch(){}!
第一步: java运行我的Hello.java类
第二步: 加载Hello.class文件
第三步: 准备运行你的main方法 运行main方法的时候 他就给偷偷的加了个try catch,然后在catch里面进行处理然后打印
public class Hello{
try{
public static void main(String[] args) {
System.out.println(1/0);
}
}catch(RuntimeException e){
e.printStackTrace();
}
}
finally 最终执行块
finally最终执行块是用在 try catch 里面的,不管try里面的代码有没有抛出异常,只要执行完了就会跑到finally里面执行
try{
System.out.println(1/0);
}catch(Exception e){
e.printStackTrace();
}finally{
System.out.println("上面的代码出错了");
}
throws 抛出异常
1. throw和throws是用于把异常丢出去给调用的人进行处理,一般 RuntimeException 下面的异常不用抛出去,因为这是属于运行时异常,java中代码编译完成后默认加 catch 进行处理的,但是 Exception 下面的异常就需要进行处理了,具体怎么处理有两种方式,第一种就是上面说过的自己写一个 try catch 自己进行处理,第二种就是通过throws 丢出去给别人处理,所谓的别人就是这个方法的调用者
自定义异常 throw
有些时候自己写项目的,需要用到自己自定的异常,自己定义的异常就需要使用throw,用于创建异常对象然后抛出去让别人进行处理,自定义异常首先你要选好继承的类,选择继承的类后那么你实现起来就非常方便了,写法和抛出如下图
import java.io.Serializable;
public class UserExpirationException extends RuntimeException implements Serializable {
private static final long serialVersionUID = 14455733833039552L;
public UserExpirationException() {
super("用户登录信息已过期,请重新登录");
}
public UserExpirationException(String message) {
super(message);
}
}
上图自定义异常类定义好了我们来开始测试如下,由于他继承是 RuntimeException,所以不用throws抛出异常给别人处理,系统会自动处理
public static void main(String[] args) {
throw new UserExpirationException();
}
############################################### 控制台输出结果如下 #################################
Exception in thread "main" com.shustudio.common.exception.UserExpirationException: 用户登录信息已过期,请重新登录
at com.shustudio.common.exception.UserExpirationException.main(UserExpirationException.java:25)
public static void main(String[] args) {
throw new UserExpirationException("找不着登陆的用户");
}
############################################### 控制台输出结果如下 #################################
Exception in thread "main" com.shustudio.common.exception.UserExpirationException: 找不着登陆的用户
at com.shustudio.common.exception.UserExpirationException.main(UserExpirationException.java:25)