07Java 异常篇


异常

异常机制提供了程序退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器

Java类库的每个包中都定义有异常类,所有这些类都是 Throwable类 的子类,有两个子类分别是 Error类、Exception类

Error类 是描述java运行系统中的内部错误以及资源耗尽的错误,属于较为致命的错误

Exception类 是可以通过捕捉处理使程序继续运行,属于非致命的错误

常见异常

异常类 说明
ClassCastException 类型转换异常类
ClassNotFoundException 没找到相应类异常
ArithmeticException 算术条件异常
ArrayIndexOutOfBoundsException 数组索引越界异常
ArrayStoreException 数组中包含不兼容的值抛出的异常
SQLException 操作数据库异常类
NullPointerException 空指针异常
NoSuchFieldException 字段未找到异常
NoSuchMethodException 方法未找到抛出的异常
NumberFormatException 字符串转换为数字抛出的异常
NegativeArraySizeException 数组长度为负异常
StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
IOException 操作输入流和输出流时异常
IllegalAccessException 不允许访问某类异常
InstantiationException 当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常
EOFException 文件已结束异常
FileNotFoundException 文件未找到异常

捕捉异常

异常捕捉有两种,自动捕捉异常(系统自带)、try-catch 语句捕捉异常

try{
   被捕获代码的区块
}catch(异常类型 e){
   对异常处理的区块
}catch(异常类型 e){
   对异常处理的区块
}catch(异常类型 e){
   对异常处理的区块
}finally{
    最后运行的区块
}

try:语句用来存放可能发生异常的语句
catch:激发被捕获的异常类型
finally:异常处理的最后运行的区域

public class Demo {
    public static void main(String[] args) {

        try{
            int i = 1/0;
        }catch (Exception e){

            //输出异常错误性质
            System.out.println(e.getMessage());
            System.out.println("--");

            //输出异常类型和性质
            System.out.println(e.toString());
            System.out.println("--");

            //输出异常类型、性质、栈层(出现位置不定)
            e.printStackTrace();
            System.out.println("--");

        }finally{
            System.out.println("END.....");
        }

    }
}

运行结果

/ by zero
--
java.lang.ArithmeticException: / by zero
--
--
END.....
java.lang.ArithmeticException: / by zero
    at Demo.main(Demo.java:5)

finally语句不会执行情况:

  • 在finally语句块中发生了异常
  • 在前面的代码中使用了 System.exit()(退出程序)
  • 程序所在的线程死亡(运行时终止程序)
  • 关闭CPU

自定义异常

创建API中没有的异常,自定条件的异常

使用步骤:

  1. 创建自定义异常类
  2. 在方法中通过 throw 关键字 抛出异常对象
  3. 如果在当前抛出异常的方法中处理异常,可以使用 try-catch语句块捕获并处理,否则在方法的声明处通过 throws关键字 指明要抛出给方法调用者的异常
  4. 在出现异常方法的调用者中捕获并处理异常
class 自定义异常类 extends 已有的异常类{···}
public class Demo {
    public static void main(String[] args) {

        orangutan xingxing = new orangutan();
        bird niao = new bird();
        key yaoshi = new key();

        //No.1
        try {
            if (!(xingxing instanceof Animals)){
                throw new CustomException("非动物"+xingxing);
            }
            System.out.println("开始1");
        } catch (CustomException e) {
            e.printStackTrace();
        }

        //No.2
        try {
            if (!(niao instanceof Animals)){
                throw new CustomException("非动物"+niao);
            }
            System.out.println("开始2");
        } catch (CustomException e) {
            e.printStackTrace();
        }

        //No.3 类型错误
        try {
            throw new CustomException("非动物:"+yaoshi);
        } catch (CustomException e) {
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

//动物类
class Animals{ }

//猩猩
class orangutan extends Animals{ }

//鸟
class bird extends Animals { }

//物品类
class Items{ }

//钥匙
class key extends Items{ }

//自定义异常类 继承异常类
class CustomException extends Exception{

    public CustomException(String message){
        super(message);
    }

}

运行结果

开始1
开始2
CustomException: 非动物:key@133314b
    at Demo.main(Demo.java:30)

方法中抛出异常

方法出现异常,又不想在当前方法处理,则可以用 throws、throw 关键字 在方法中抛出异常

throws 关键字抛出异常

throws将代码中可能产生的异常交给上一级处理,直到处理异常 try-catch 语句调用 ,否则调用的那个方法也要加抛出的关键字已经方法类

public void 方法名() throws 异常类型1,...,异常类型n{  }

被调用时:

try{
    方法名();
}catch(异常类型 e){
    e.printStackTrace();
}
public class Demo {
    //抛出中断异常
    public static void show() throws InterruptedException ,ArithmeticException{

        for (int i = 0; i <= 10 ; i++) {
           System.out.println(i);

           Thread.sleep(1000);

           if (i == 5){
               i-=5;
               int s = 1/i;
           }

        }
    }

    public static void main(String[] args) {

        //获取方法中的异常
        try {
            show();
            //终止异常
        } catch (InterruptedException e) {
            System.out.println("show()方法抛出终止异常");
            //算术异常
        }catch (ArithmeticException e) {
            System.out.println("show()方法抛出算术异常");
            //异常
        }catch (Exception e) {
            System.out.println("show()方法抛出异常");
        }

    }
}

运行结果

0
1
2
3
4
5
show()方法抛出算术异常

throw 关键字抛出异常

手动制造异常。程序运行到throw语句时立即终止程序,不会执行后面的语句

使用throw抛出异常的前提,必须要有try-catch语句包围捕捉异常

public class Demo2 {
    public static void main(String[] args) {
        int a = 1 , b = 0 ;
        try {
            if (b == 0){
                //强制中断
                throw new NullPointerException("b 为 0");
            }
            int s = a / b ;
        } catch (NullPointerException e) {
            e.printStackTrace();
        }

    }
}

运行结果

java.lang.NullPointerException: b 为 0
    at Demo2.main(Demo2.java:7)

异常的使用原则

提高程序的安全性,控制流程状况以及异常修复!

  • 不要怱略捕捉到的异常
  • 不要过度使用异常
  • 不要使用过于庞大的 try-catch语句
  • 子类抛出的异常不能比父类高级(RuntimeException不受此约束)
  • 一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类

文章作者: 柏竹
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 柏竹 !
评论
  目录