【1】Java异常

一、异常分类

  • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
  • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
  • 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
Throwable(异常根类) Error(错误) VirtualMachineError 虚拟机错误  
OutOfMemoryError内存溢出  
ThreadDeath线程死锁  
Exception(异常)

RuntimeException(运行时异常)
(非检查异常)

NullPointerException(空指针异常)
ClassCastException(类型转换异常)

ArraylndexOutOfBoundException

(下标越界异常)

ArithmeticException(算数异常)

Checked Exceptions(检查异常)
(非运行时异常)

IOException(IO异常)
SQLException(SQL异常)

二、异常处理

1、捕获异常:try-catch-finally

代码形式:

    try{
    //代码段1
    //产生异常的代码段2
    }catch(异常类型 ex){
    //对异常进行处理的代码段3
    }finally{
    //代码段四
    }

 

补充
catch语句块中有System.exit(非零整数);则表示当前程序无条件终止运行,后面的语句不再执行 
 
 实例:
import java.util.InputMismatchException;
import java.util.Scanner;

public class TryDemoOne {
    /**
     * 多重catch语句,与执行顺序有关,当捕获到了一个异常时,剩下的catch语句就不再进行匹配。
     * @param args
     */
    public static void main(String[] args) {

        // 要求:定义两个整数,接受用户的键盘输入,输出两数之商
        Scanner input=new Scanner(System.in);

        try{
            System.out.print("请输入第一个整数:");
            int one=input.nextInt();
            System.out.print("请输入第二个整数:");
            int two=input.nextInt();
            System.out.println("one和two的商是:"+ (one/two));
        }catch(ArithmeticException e){
            System.exit(1);//终止程序运行
            System.out.println("除数不允许为零");
            e.printStackTrace();//打印错误的描述、类型、位置
        }catch(InputMismatchException e){
            System.out.println("请输入整数");
            e.printStackTrace();
        }catch(Exception e){
            System.out.println("出错啦~~");
            e.printStackTrace();
        }finally{//无论是否有异常,都会执行finally的语句块
            System.out.println("=====运算结束=====");
        }
    }

}
View Code

 

2、声明异常类型:throws

1.)throws语句用在方法定义时什么该方法要抛出的异常类型。
2.)当方法抛出异常列表中的异常时,方法将不对这些类型及其子类型的异常做处理,谁调用这个方法则谁处理抛出的异常。

public void method()throws Exception1,Exception2,....,ExceptionN{
        //可能产生异常的代码
    }

 实例:

import java.util.InputMismatchException;
import java.util.Scanner;

public class test {

    public static void main(String[] args) {

        try{
            int result = test();
            System.out.println("one和two的商是:" + result);
        }catch(ArithmeticException e){

        }catch(InputMismatchException e){

        }catch(Exception e){

        }
        int result2=test();
    }

    /*通过throws抛出异常时,针对可能出现的多种异常情况,解决方案:
     * 1、throws后面接多个异常类型,中间用逗号分隔
     * 2、throws后面接Exception
     * */
    /**
     * 测试接收数据相除结果的方法
     * @return 两个接收数据的商
     * @throws ArithmeticException
     * @throws InputMismatchException
     */
    public static int test() throws ArithmeticException,InputMismatchException{
        Scanner input = new Scanner(System.in);
        System.out.println("=====运算开始=====");
        System.out.print("请输入第一个整数:");
        int one = input.nextInt();
        System.out.print("请输入第二个整数:");
        int two = input.nextInt();
        System.out.println("=====运算结束=====");
        return one / two;
    }

}
View Code

 

3、抛出异常对象:throw

1. throw用来抛出一个异常对象,例如:throw new IOException();
2. throw抛出的只能是Throwable或者是其子类的实例对象。
3. throw抛出异常对象的处理方案(具体格式如截图所示):
1)自己抛出自己处理,通过try-catch包含throw语句。
2)用throws往上抛,调用者可以try-catch处理或者继续往上抛。throws抛出异常类型时,要抛出与throw对象相同的类型或者其父类。
(例如:throw new Exception(); 那么可以throws Throwable)

4. 如果throw抛出的异常对象为InputMismatchException这样的非检查型异常,编译器不会强制要求必须进行异常处理。
5. 在程序中使用throw主动抛出异常对象的目的
1)规避可能出现的风险
2)完成程序逻辑

 实例:

import java.util.Scanner;

public class TryDemoFour {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            testAge();
        } catch (HotelAgeException e) {
            System.out.println(e.getMessage());
            System.out.println("酒店前台工作人员不允许办理入住登记");
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /*
     * throw抛出异常对象的处理方案:
     * 1、通过try..catch包含throw语句--自己抛自己处理
     * 2、通过throws在方法声明出抛出异常类型--谁调用谁处理--调用者可以自己处理,也可以继续上抛
     *    此时可以抛出与throw对象相同的类型或者其父类
     */
    //方法1:自己处理异常
    // 描述酒店的入住规则:限定年龄,18岁以下,80岁以上的住客必须由亲友陪同
    /*public static void testAge() {

        try {
            System.out.println("请输入年龄:");
            Scanner input = new Scanner(System.in);
            int age = input.nextInt();
            if (age < 18 || age > 80) {
                throw new Exception("18岁以下,80岁以上的住客必须由亲友陪同");
            } else {
                System.out.println("欢迎入住本酒店");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }*/
    //方法2:方法调用处去处理异常
    public static void testAge() throws HotelAgeException {
        System.out.println("请输入年龄:");
        Scanner input = new Scanner(System.in);
        int age = input.nextInt();
        if (age < 18 || age > 80) {
            //throw new ArithmeticException();
            //throw new Exception("18岁以下,80岁以上的住客必须由亲友陪同");
            throw new HotelAgeException();
        } else {
            System.out.println("欢迎入住本酒店");
        }
    }
}
View Code

 

 

三、自定义异常

1. 使用Java内置的异常类可以描述在编程时出现的大部分异常情况。

2. 也可以通过自定义异常描述特定业务产生的异常类型。所谓自定义异常,就是定义一个类,去继承Throwable类或者它的子类。

public class HotelAgeException extends Exception {
   public HotelAgeException(){
      super("18岁以下,80岁以上的住客必须由亲友陪同");
   }
}

class SubException extends HotelAgeException{
   
}
自定义异常类

 

public class test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            testAge();
        } catch (HotelAgeException e) {
            System.out.println(e.getMessage());
            System.out.println("酒店前台工作人员不允许办理入住登记");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static void testAge() throws HotelAgeException {
        System.out.println("请输入年龄:");
        Scanner input = new Scanner(System.in);
        int age = input.nextInt();
        if (age < 18 || age > 80) {
            //throw new ArithmeticException();
            //throw new Exception("18岁以下,80岁以上的住客必须由亲友陪同");
            throw new HotelAgeException();
        } else {
            System.out.println("欢迎入住本酒店");
        }
    }
}
View Code

 

 

四、异常链

1、异常链:有时候我们会捕获一个异常后再抛出另一个异常,将异常发生的原因一个传一个串起来,即把底层的异常信息传给上层,逐层抛出,这就是异常链。

2、抛出最上层异常时仍旧保留底层异常信息的方法:

1)可以调用Throwable(String message,Throwable cause)的构造方法来保留底层异常的异常信息

2)或者采取"Throwable对象.initCause(Throwable cause) "的方法用来获取原始异常的描述信息,其中cause是原始异常的对象

public class TryDemoFive {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            testThree();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void testOne() throws HotelAgeException {
        throw new HotelAgeException();
    }

    public static void testTwo() throws Exception {
        try {
            testOne();
        } catch (HotelAgeException e) {
            throw new Exception("我是新产生的异常1",e);
        }
    }

    public static void testThree() throws Exception {
        try {
            testTwo();
        } catch (Exception e) {
            Exception e1=new Exception("我是新产生的异常2");
            e1.initCause(e);
            throw e1;
//            throw new Exception("我是新产生的异常2",e);
        }
    }
}
View Code

 

posted @ 2020-06-08 21:42  柠檬不萌!  阅读(187)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end