java基础(七):异常

异常

  • 程序运行出现了不正常的情况

  • Java中提供的用于对程序出现的问题做反馈处理的机制

Throwable

  • 包:java.lang

  • 类定义:public class Throwable

  • Throwable 类是 Java 语言中所有错误或异常的超类

  • 子类:

    • Error:严重问题,非人力可以解决,例如:栈内存溢出异常(java.lang.StackOverflowError)

      • 注意:Error一般不进行处理,确保程序逻辑没有问题即可

      • JVM默认处理的方式:以红色字体打印异常详细信息

    • Exception:

      • 编译时异常(已检查异常):除了RunTimeException其他都是编译时异常,例如ParseException
        • 编译时异常在程序编译期间就会被检查出来,并提示;要求必须处理
      • 运行时异常(未检查异常):RunTimeException,例如:java.lang.ArithmeticException
        1. 运行时异常检测不出来,所以编译期不会有提示;可以不处理,如果不处理,该异常交给JVM处理
        2. JVM默认处理的方式:以红色字体打印异常详细信息
        3. JVM默认处理的缺点:一旦程序抛出异常,则程序立即停止运行

异常的处理机制

throws抛出异常

throws 异常类名
  • 位置:异常代码所属的方法声明上,跟在方法名 参数列表后面
  • 注意
    1. throws将问题抛出给了方法的调用者,当真正出现异常时,JVM默认处理的方式:以红色字体打印异常详细信息
    2. 一旦出现异常,抛出的情况下,程序会停止执行
    3. 编译时异常必须处理,运行时异常可以通过throws抛出也可以不处理
    4. 如果程序中有多个异常可以通过 throws 异常类名1, 异常类名2, …抛出
    5. 可以在throws后面写Exception或者Throwable,此时不管程序抛出什么类型的异常,父类都可以接收
    6. 缺点:一旦程序抛出异常,则程序立即停止运行
public class ExceptionDemo2 {
    public static void main(String[] args) throws Exception {
        method();
    }

    public static void method() throws Exception {
        // DateFormat formate = new SimpleDateFormat("yyyy-MM-dd");
        // ParseException 编译时异常
        // 抛出异常给方法的调用者
        // 一旦出现异常抛出的情况下,程序无法执行
        DateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        Date date = format.parse("2021-11-23");
        System.out.println(date);
        System.out.println("hello");

        // 运行时异常
        int a = 5;
        int b = 0;
        System.out.println(a/b);
    }
}

try catch

// 格式1
try {
    可能出现异常的代码;
} catch(异常类 变量){
    异常处理的代码
}
// 格式2
try {
    可能出现异常的代码;
} catch (异常类1 变量1){
    异常处理的代码;
} catch (异常类2 变量2){
    异常处理的代码;
} catch (异常类3 变量3){
    异常处理的代码;
}
  • 此格式可以直接写异常的父类 Exception Throwable,可以接收任意类型的异常;实际开发中,建议能细致处理的异常要详细处理。

示例:

public class ExceptionDemo4 {
    public static void main(String[] args) {
        // 抛出多个异常时的简化代码
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        int a = 5;
        int b = 0;
        try {
            Date date = format.parse("2021-11-23");
            System.out.println(date);
            System.out.println(a/b);
        } catch(Exception e){
            System.out.println(e.getMessage());
        }
        System.out.println("end!");
    }
}
// 格式3
try {
    可能出现异常的代码;
} catch(异常类1|异常类2|异常类3 变量){
    异常处理的代码;
}

示例:

public class ExceptionDemo4 {
    public static void main(String[] args) {
        // 格式 3 
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        int a = 5;
        int b = 0;
        try {
            Date date = format.parse("2021-11-23");
            System.out.println(date);
            System.out.println(a/b);
        } catch(ParseException | ArithmeticException e){
            System.out.println(e.getMessage());
        }
        System.out.println("end!");
    }
}
  • 此格式异常类必须时平级的,不能存在父子类关系
  • JDK1.7开始提供的方案
  • 应用场景:在实际开发中,当抛出的异常是同类型异常时才会使用该方案;
// 格式4
try {
    可能出现异常的代码;
} catch(异常类 变量){
    异常处理的代码;
} finally{
    代码块;
}
  • finally和try 语句结合使用
  • finally作用:资源释放
  • 特点:无论try中是否抛出异常,finally中的代码都要执行一次
  • 实际开发中的应用:io流的释放,数据库相关的内容释放

示例:

public class ExceptionDemo8 {
    public static void main(String[] args) {
        DateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        Date date;
        try {
            date = format.parse("2021-11-23");
            System.out.println(date);
        } catch(ParseException e){
            System.out.println(e.getMessage());
        } finally {
            date = null;  // 释放资源
        }
        System.out.println("end!");
    }
}

注意:

  1. try中尽量只包含会出现异常的代码,其他代码越少越好,避免影响程序的运行效率

  2. catch中一定要有异常处理的代码,否则一旦有异常,异常信息就会被隐藏掉

  3. 无论是否有异常产生,try catch之后的代码都会正常执行;如果有异常产生,则try中异常之后的代码不再执行

  4. 编译时异常和运行时异常都可以通过try catch来处理

  5. 在catch中可以嵌套try catch语句

    public class ExceptionDemo5 {
        public static void main(String[] args) {
            try {
                System.out.println(5/0);
            } catch(ArithmeticException e){
                System.out.println(e.getMessage());
                try {
                    System.out.println(6/0);
                } catch(Exception e1){
                    System.out.println(e1.getMessage());
                }
            }
        }
    }
    

throw 和 throws

  • throw

    • 用于手动抛出异常
    • 一般会通过throws来继续向上抛出
    public class ExceptionDemo6 {
        public static void main(String[] args) throws Exception{
            int age = -20;
            if (age < 0){
                // System.out.println("年龄输入错误");
                // 手动抛出异常
                throw new Exception();
            }
        }
    }
    
  1. 位置不同

    throw在方法中用于手动产生异常

    throws在方法声明上,用于抛出异常,解决异常

  2. 作用不同

    throw用于手动产生异常

    throws用于抛出异常,解决异常

  3. 内容有区别

    throw后边跟的是异常的对象

    throws后边则是异常类的类名

Throwable中的方法:

  1. String getMessage()

    返回此 throwable 的详细消息字符串。

  2. void printStackTrace()

    将此 throwable 及其追踪输出至标准错误流。

  3. String toString()

    返回此 throwable 的简短描述。

    public class ExceptionDemo6 {
        public static void main(String[] args) throws Exception{
            try {
                System.out.println(5/0);
            } catch( ArithmeticException e){
                // System.out.println(e.getMessage());
                e.printStackTrace();
                // 记录异常信息到日志文件中
                // System.out.println(e.toString());
                // 跳转到错误提示页面
            }
            System.out.println("end!");
        }
    }
    

自定义异常

  • 定义一个类,此类必须继承Exception / Throwable / RuntimeException

  • 提供有参构造,可以传入异常的详细描述

  • 自定义异常和业务功能绑定较多,实际项目开发中使用较多

    /*自定义异常*/
    public class MyException extends Exception{
        // 必须继承 Exception 或Throwable
        public MyException(){
            super();
        }
        public MyException(String message){
            super(message);
        }
    }
    /*测试类*/
    public class ExceptionDemo7 {
        public static void main(String[] args) throws MyException {
            int age = -20;
            if (age < 0){
                throw new MyException("年龄应当大于0");
            }
        }
    }
    

异常对方法重载和方法重写的影响

  • 异常的抛出并不影响方法重载

  • 方法重写:两等两小一大

    • 两等:

      1、方法名、参数列表一致

      2、如果返回值类型是基本数据类型或void,则重写的方法必须一致

    • 两小:

      1、 如果返回值类型是引用类型,则子类方法返回值类型必须和父类返回值类型一致或者是子类类型

      2、子类中方法抛出的异常类型必须小于等于父类方法抛出的异常类型

    • 一大:

      子类的访问权限修饰符必须大于父类的访问权限修饰符

    public class ExceptionDemo1 {
        public static void main(String[] args) throws Exception{
            Person p = new Student();
            p.method();
        }
    }
    
    class Person{
        public void method() throws Exception{
            System.out.println("Person");
        }
    }
    class Student extends Person {
        @Override
        public void method() throws ParseException {
            DateFormat d = new SimpleDateFormat("yyyy-MM-dd");
            d.parse("2021-11-25");
            System.out.println("Student");
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值