Java基本语法(七)—— 异常

123 阅读3分钟

1.概述

异常:程序执行中的不正常情况

  • Error:JAVA虚拟机不能解决的问题,如JVM内部错误、资源耗尽(栈溢出:StackOverflowError、堆溢出:OOM)。
  • Exception:其它因编程错误或偶然的外部因素导致的一般性问题,可以使用针对性代码进行处理。如空指针、读取文件不存在、网络连接中断、数组越界。

异常体系结构:

java.lang.Throwable,包含两个子类:

  • java.lang.Error:一般不编写针对针对性代码处理。

  • jave.lang.Exception

    • 编译时异常(checked):IOException、ClassNotFoundException...
    • 运行时异常RuntimeException(unchecked):NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、NumberFormatException、ArithmeticException、InputMismatchException...

2.异常处理机制一:try-catch-final

Java中提供处理异常的:抓抛模型——“抛“、”抓“

”抛“:程序执行过程中出现异常,就会在异常处生成一个对应异常类的对象,并将此对象抛出。异常后的代码不再执行。

”抓“:异常处理的方法——try-catch-finalthrows

try-catch-final的使用

 try{
 //可能出现异常的代码
 }catch(异常类型1 变量名1){
     //处理异常的方式1
 }catch(异常类型2 变量名2){
     //处理异常的方式2
 }....//可以有多个catch
 finally{
     //一定会执行的代码
 }

注意几点:

  1. try将可能出现异常的代码包装起来,一旦出现异常就生成一个对应异常类的对象,根据此对象类型到catch中匹配。
  1. 异常对象匹配到某个catch,就进入这个catch进行异常处理。处理完成就跳处try-catch,继续执行后边的代码(无finally时)
  1. 其中finally是可选的。
  2. catch中的异常,子类要声明在父类之前(如NumberFormatException和NullPointerException顺序无所谓,但一定要在Exception之前)
  3. catch中常用的异常对象处理方式:a. String getMessage() , b. void printStackTrace()
  4. try结构中定义的变量只能在try内部使用。
  5. try-catch结构可以嵌套

关于finally:

  1. finially中的代码一定会被执行,即使有以下情况:catch中出现异常、try和catch中有return语句。
  2. 以下内容可以考虑放在finally中:关于数据库连接、IO流、网络编程Socket等JVM不可回收的资源的资源释放。

3.异常处理机制二:throws

使用:方法声明处 throws 异常类型 {方法体}

表示一旦方法体执行出现异常,仍会在代码异常处生成异常类对象,此对象满足throws后的异常类型后就会被抛出。出现异常后的代码也不会执行。

throws只是将异常抛给了方法的调用者,真正处理异常的还是try-catch-finally。

如何选择try-catch-finally和throws类型?

  1. 父类中被重写的方法没有用throws处理异常,则子类中被重写的方法也不能使用throws。即子类中的被重写方法必须使用try-catch-finally方式处理。
  2. 执行某方法a时,调用了几个方法b、c、d...,且b,c,d等方法是递进的(b的结果要作为c方法的参数,以此类推)。建议b、c、d等方法用throws处理异常,方法a用try-catch-finally处理异常。

4.手动抛出异常:throw

手动生成一个异常对象,并抛出:throw new 异常类型

 public class ExceptionTest {
     public static void main(String[] args) {
         Student test = new Student();
         try{
             test.setId(-1);
         }catch(Exception e){
             System.out.println(e.getMessage());
             //只打印:您想赋予的id值非法(<=0)
         }
     }
 }
 ​
 class Student{
     int id;
     public void setId(int id) throws Exception {//向调用本方法的地方抛异常
         if(id > 0){
             this.id = id;
         }
         else{
             throw new RuntimeException("您想赋予的id值非法(<=0)");
             //手动生成异常;注意:此处不要new Throwable对象
         }
     }
 }

5.用户自定义异常类

定义方法:

  1. 继承现有异常类。
  2. 提供serialVersionUID,用于唯一标识定义的异常类。
  3. 提供重载的构造器。
 //1.继承:这里可以继承 RunTimeException或Exception(此时包含编译时异常)
 public class MyException extends RuntimeException {
 ​
     //2.提供serialVersionUID
     static final long serialVersionUID = -7034897421907766939L;
     
     //3.构造器:
     public MyException(){}
     public MyException(String msg){
         super(msg);//相当于getMessage
     }
 }