Java基础学习笔记:第六章 异常处理

异常处理

异常 : 程序在运行时出现的非正常状况. 异常会导致程序崩溃

异常的分类 :

  1. 按照程度来分

    1. Error 严重错误:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。一般不编写针对性的代码进行处理。
    2. Exception 一般问题:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。
  2. 按照处理方式来分

    1. 受检异常(checked) 在程序中必须接受检查和处理的异常. 如果不处理编译错误,也称为编译时异常
      Exception及其子类(RuntimeException及其子类除外)
    2. 非受检异常(unchecked) 在程序中不是必须接受检查和处理的异常, 如果不处理不生编译错误, 但是运行时仍会出问题, 也称为运行时异常
      Error及其子类.
      RuntimeException及其子类.

在这里插入图片描述

常见异常:
java.lang.RuntimeException 
ClassCastException
ArrayIndexOutOfBoundsException
NullPointerException
ArithmeticException

java.io.IOExeption
FileNotFoundException
EOFException
java.lang.ClassNotFoundException
java.lang.InterruptedException
java.io.FileNotFoundException
java.sql.SQLException

异常的堆栈式抛出机制

在这里插入图片描述

异常对象的生成

一、由虚拟机自动生成:程序运行过程中,虚拟机检测到程序发生了问题,如果在当前代码中没有找到相应的处理程序,就会在后台自动创建一个对应异常类的实例对象并抛出——自动抛出

二、由开发人员手动创建:Exception exception = new ClassCastException();——创建好的异常对象不抛出对程序没有任何影响,和创建一个普通对象一样

对异常的处理

通常有三种处理异常的方式:

捕获(使用try-catch-finally语句)
直接抛出(方法声明)
捕获再抛出

以上处理方式适用于Exception类型的受检异常和RuntimeException类型的非受检异常。
受检异常必须由程序显式处理

  1. 捕获
   try {
      可能抛出异常的语句;
  } catch (可能的异常类型1 引用) {
      对异常处理.
  } catch (可能的异常类型2 引用) {
       对异常处理.
   } .....
  catch (Exception e) {
      确保万无一失
   } finally { // final 修饰符, 修饰类, 方法, 变量
       释放不在GC区中资源, 而是由OS管理的资源. 比如文件,网络等硬件资源.
   }
 
   try catch
   try catch finally
   try finally
  1. 抛出 : 使用throws体现异常的抛出.

    在方法声明中的throws 异常类型列表, 作用是警告调用者, 此方法有风险.
    在方法体中使用throw语句, 在方法中真的抛出异常对象.
    

    可以只有throws而没有throw
    只要有throw必须要有throws

    throws 是警告
    throw 是抛出异常
    

方法覆盖条件中对于异常的描述 :
要求如下 :

     1) 方法签名一致, 子类方法的返回值的对象类型可以小于等于父类方法返回的对象类型.
     2) 子类方法的访问控制修饰符的范围要大于等于父类的.
     3) 被覆盖方法不可以被private, static, final.
     4) 子类方法抛出的受检异常范围要小于等于父类方法抛出的受检异常.
  1. 先捕获, 再抛出.
    try {
         可能抛出异常的语句;
   } catch(任意异常类型 引用) {
         throw new 自定义异常(引用);
    }

处理方式的选择 :

  1. 入口方法尽量捕获.
  2. 功能方法尽量抛出.
// 自定义异常 : 1) 继承Exception 表明它是一个异常, 2) 提供2个构造器一个String,一个是Throwable 创建自定义异常对象方便
class DividedByZeroException extends Exception { // 这是受检异常, 必须要处理

    public DividedByZeroException(String message) {
        super(message); // 间接调用到父类构造, 完成私有的detailMessage的初始化.
    }
    public DividedByZeroException(Throwable cause) { // 对象关联专用
        super(cause);
    }
}

public class ExceptionTest {

    public static int divide(int x, int y) throws DividedByZeroException {
        try {
            return x / y;
        } catch (ArithmeticException e) {
            throw new DividedByZeroException(e); // 包装 : 自定义异常对象内部包含一个其他异常对象.
        }
    }

    public static void main(String[] args) {
        try {
            try {
                System.out.println(divide(10, 2));
                System.out.println(divide(10, 0));
            } catch (DividedByZeroException e) {
                System.out.println(e.getMessage());
            }
            System.out.println(divide(20, 5));
        } catch (DividedByZeroException e) {
            e.printStackTrace();
        } finally {
            System.out.println("finally");
        }
    }
}

class ExceptionTest3 {
    // throws的作用是警告调用者, 调用此方法有风险!!!
    public static int divide(int x, int y) throws DividedByZeroException { // throws和throw最好要一致, 显得诚实
        if (y == 0) {
            // 真的抛出一个异常对象, 当前方法就会提前弹栈返回结束, 并给调用者产生破坏.
            throw new DividedByZeroException("除数不可以为0错误!!!!");
        }
        return x / y;
    }

    //public static void main(String[] args) throws DividedByZeroException { main方法虽然可以抛出异常, 但是不要抛.
    public static void main(String[] args) {
        try {
            System.out.println(divide(10, 2));
            System.out.println(divide(10, 0));
        } catch (DividedByZeroException e) {
            System.out.println(e.getMessage());
        }

        System.out.println("end");
    }
}

class ExceptionTest2 {

    public static int divide(int x, int y) {
        if (y == 0) {
            RuntimeException re = new RuntimeException("除数不可以为0"); // throw和return效果一样, 都是让方法返回的
            throw re;
            // return 是和平返回, throw 带有破坏性的返回.
        }
        return x / y;
    }

    public static void main(String[] args) {
        try {
            System.out.println(divide(10, 2));
            System.out.println(divide(10, 0));
        } catch (RuntimeException e) {
            System.out.println(e.getMessage());
        }
        System.out.println("end...");
    }
}


class ExceptionTest1 {

    public static void main(String[] args) {
        System.out.println("main begin");

        boolean b = true;
        if (b) {
            //return;
        }

        try {
            int n = Integer.parseInt(args[0]);
            System.out.println(n);
            return;
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println(e);
        } catch (NumberFormatException e) {
            System.out.println(e.getMessage());
        } catch (Exception e) {
            System.out.println("其他可能的异常 : " + e);
        } finally {
            // 无论前面try catch中发生什么, 我都要执行....
            System.out.println("finally");
        }

        System.out.println("main end");
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值