JAVA基础总结(十一)JAVA 异常详解 及一些异常的解决办法

本文详细介绍了Java异常处理机制,包括异常的分类、常见异常类型、异常处理方法(捕获和抛出)、自定义异常以及使用注意事项。重点讨论了运行时异常和受检查异常的区别,并给出了实例代码展示如何有效地捕获和处理异常。此外,还提到了自定义异常的创建步骤,强调了在Java编程中合理处理异常的重要性。
摘要由CSDN通过智能技术生成

一、JAVA 异常


1、Java异常概括

       异常:程序运行过程中产生的不正常的情况统称为异常!(程序运行时产生错误)


2、Java中的异常体系

        Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。
        在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常, 这两种异常有很大的区别,也称之为非受检查异常(Unchecked Exception)和受检查异常(Checked Exception)。

在这里插入图片描述

  • 两个子类区别:

    • Error: 程序不应该捕捉的错误,应该交由JVM来处理。一般可能指非常重大的错误。这个错误我们一般获取不到,也无法处理!

    • Exception: 程序中应该要捕获的错误。这个异常类及它的子类是我们需要学习获取要处理的。



3、程序中异常的区分

(1)非运行时异常: 也叫可查异常,正确的程序在运行中,很容易出现的、情理可容的异常状况。除了Exception中的RuntimeException及RuntimeException的子类以外,其他的Exception类及其子类(例如:IOException和ClassNotFoundException)都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。

(2)运行时异常: RuntimeException 类及其子类被称为运行时异常,也叫未检查异常,是Exception的子类。不需要捕捉的异常超类,但是实际发生异常时,会导致程序停止运行的状况,只是编译时没有报错而已。比如除数为零,数组空指针等等,这些都是在运行之后才会报错。此类异常,可以处理也可以不处理,并且可以避免。而且这个问题的出现肯定是我们的代码不够严谨,需要修正代码。



4、JAVA 中几种常见的异常:

  • RuntimeException子类:
异常名称异常描述
java.lang.ArrayIndexOutOfBoundsException数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
java.lang.ArithmeticException算术条件异常。譬如:整数除零等。
java.lang.SecurityException安全性异常
java.lang.IllegalArgumentException非法参数异常
java.lang.ArrayStoreException数组中包含不兼容的值抛出的异常
java.lang.NegativeArraySizeException数组长度为负异常
java.lang.NullPointerException空指针异常。当应用试图在要求使用对象的地方使用了 null 时,抛出该异常。譬如:调用 null 对象的实例方法、访问 null 对象的属性、计算 null 对象的长度、使用 throw 语句抛出 null 等等。
  • IOException
异常名称异常描述
IOException操作输入流和输出流时可能出现的异常
EOFException文件已结束异常
FileNotFoundException文件未找到异常
  • 其他异常
异常名称异常描述
ClassCastException类型转换异常类
ArrayStoreException数组中包含不兼容的值抛出的异常
SQLException操作数据库异常类
NoSuchFieldException字段未找到异常
NoSuchMethodException方法未找到抛出的异常
NumberFormatException字符串转换为数字抛出的异常
StringIndexOutOfBoundsException字符串索引超出范围抛出的异常
IllegalAccessException不允许访问某类异常
InstantiationException当应用程序试图使用 Class 类中的 newInstance() 方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常
java.lang.ClassNotFoundException找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历 CLASSPAH 之后找不到对应名称的 class 文件时,抛出该异常。


5、异常的处理办法


1、捕获异常

  • 我们在日常开发中会遇到各种不同的错误,我们需要根据产生错误的原因去区分和处理这些错误。
    • 那么我们自己如何处理异常呢?
      • 通过 Try…Catch… finally将异常捕获并尽可能的解决
        • Try…Catch… finally 的作用
          • Try 的作用:捕捉代码块中的异常
          • Catch 的作用:Try 捕捉的异常会抛给 Catch ,可以在此模块中进行异常分类和异常的相关处理
          • finally 的作用:用于释放资源,减小程序负荷

  • Try…Catch的格式

       try {
                可能出现问题的代码;
            }catch(异常名 变量) {
                针对问题的处理;
            }finally {
                释放资源;
            }
    

try 后的catch代码块 只能匹配成功一个
catch后声明的异常为父类时,它能够捕捉的异常为它本身+所有子类异常(多态的体现)
注意:catch代码块捕获异常时,子类异常必须定义在父类异常前面,否则会编译出错


Demo代码示例:

//注:如何程序出现了问题,我们没有做任何处理,最终jvm会做出默认的处理。然后把异常的名称,原因及出现的问题等信息输出在控制台。
//所以说,看控制台很重要!!!!!!!!!

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

        int x = 9;
        int y = 0;

        //单个异常的处理
       
        /*System.out.println(x/y);*/
        //这里运行之后会报出以下错误
     /*   Exception in thread "main" java.lang.ArithmeticException: / by zero
        at JavaSE_Demo_02.Demo_10.Deme_Throwable.Demo_Exception.DemoException.main(DemoException.java:16)*/

       /* 对错误进行讲解:
       *因为Java的程序都是放在JVM上进行执行的,当程序运行时jvm发现运算是已经违反了数学运算规则,
       * java将这种常见的问题进行描述,并封装成了对象叫做ArithmeticException
        当除0运算发生后,jvm将该问题打包成了一个异常对象。
        并将对象抛给调用者main函数,new ArithmeticException(“/by zero”);

        main函数收到这个问题时,有两种处理方式:
        1. 自己将该问题处理,然后继续运行
        2.自己没有针对的处理方式,只有交给调用main的jvm来处理

        jvm有一个默认的异常处理机制,就将该异常进行处理,并将该异常的名称,异常的信息.异常出现的位置打印在了控制台上
        同时将程序停止运行
       * */

///
       
        //当发现这些错误的时候,Java为我们提供了处理异常的方式,Try…Catch,将异常捕获。并且还可以在 catch 体中做自己的逻辑处理,catch中主要是做代码异常的处理

       /* 如果一段代码存在多个错误,这时候如果每个问题都去try的话会显得很琐碎,可以使用多个catch来解决
        (和 if (){}|else的格式很类似,同理catch也是只执行一个,执行完就跳出Try…Catch)*/

        //注:如果写的是多个catch体,那么异常类型会选择最大的异常来打印,如果异常等级是一样的,那么就按顺序来
        //    所以在捕获异常时,需要按照从小到大的顺序来捕获

       try {
            System.out.println(x/y);
        }catch (Error error){
            if(x !=0 && y !=0){
                System.out.println(x/y);
            }else {
                System.out.println("除数不能为0");
            }
            System.out.println("Error");
        }catch (Exception exception){
            if(x !=0 && y !=0){
                System.out.println(x/y);
            }else {
                System.out.println("除数不能为0");
            }
            System.out.println("Exception");
        }catch (Throwable throwable){
            if(x !=0 && y !=0){
                System.out.println(x/y);
            }else {
                System.out.println("除数不能为0");
            }
            System.out.println("Throwable");
        }finally {
            System.out.println("释放资源");
        }
    }

}

运行结果:

在这里插入图片描述

通过运行结果可以发现,一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配,一旦有匹配的,就执行catch里面的处理,然后结束了try…catch继续执行后面的语句。


2、抛出异常


1、throws
        有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。或者说,我处理不了,我就不处理了。
        为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出。
  • 格式:
    • throws 异常类名
    • 注意:这个格式必须跟在方法的括号后面。

Demo代码示例:

public class DemoExceptionThrows {

    public static void main(String[] args) {
    
        try {
            method();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println("但是我要在家学习");

        method2();
    }

    // 编译期异常的抛出,编译不通过,我们就要抛出异常了
    public static void method() throws ParseException {
        String s = "2016-09-03";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = sdf.parse(s);
        System.out.println(d);
    }

    // 运行期异常的抛出
    public static void method2() throws ArithmeticException {
        int a = 10;
        int b = 0;
        System.out.println(a / b);
    }

}

2、throw
  • 手动产生异常:throw
    • 格式:throw new 异常类名();

  • throws和throw的区别

    • throws

      • 用在方法声明后面,跟的是异常类名
      • 可以跟多个异常类名,用逗号隔开
      • 表示抛出异常,由该方法的调用者来处理
      • throws表示出现异常的一种可能性,并不一定会发生这些异常
    • throw

      • 用在方法体内,跟的是异常对象名
      • 只能抛出一个异常对象名
      • 表示抛出异常,由方法体内的语句处理
      • throw则是抛出了异常,执行throw则一定抛出了某种异常

手动抛出异常的代码示例:

public class DemoThrow {


        public static void main(String[] args) throws Exception {
            m1();
        }

        public static void m1() throws Exception {
            System.out.println("m1----------start");
            m2();
            // 手动抛出受查异常
            throw new Exception();
            //System.out.println("m1----------end");
        }

        public static void m2() {
            System.out.println("m2----------start");
            // 手动抛出运行时异常,需要携带信息“程序因为异常而终止”
            throw new RuntimeException("程序因为异常而终止");
            //System.out.println("m2----------end");
        }


}

运行结果:
在这里插入图片描述

6、自定义异常

        java不可能对所有的情况都考虑到,所以,在实际的开发中,我们可能需要自己定义异常。而我们自己随意的写一个类,是不能作为异常类来看的,要想你的类是一个异常类,就必须继承自Exception或者RuntimeException。

自定义异常类的使用步骤如下:

1、自定义异常类继承 Exception 类

/**
 * 自定义异常类
 */
public class MyException extends Exception {
    //异常信息
    private String message;

    //构造函数
    public MyException(String message){
        super(message);
        this.message = message;
    }

    //获取异常信息,由于构造函数调用了super(message),不用重写此方法
    //public String getMessage(){
    //    return message;
    //}
}

2、在要抛出异常的函数使用throws关键字

/**
 * 在需要抛出异常的地方使用异常类
 */
public class UseMyException {
    private String name;
    private String password;

    public UseMyException(String name,String password){
        this.name = name;
        this.password = password;
    }

    public void throwException(String password) throws MyException{
        if (!this.password.equals(password)){
            throw new MyException("密码不正确!");
        }
    }
}

3、测试,使用try-catch处理异常

/**
 * 测试异常
 */
 	public class TestException {

    public static void main(String[] args) {
        UseMyException ex = new UseMyException("admin","123");
        try{
            ex.throwException("1234");
        }catch (MyException me){
            System.out.println("MyException:"+me.getMessage());
        }
    }

}

运行结果:
在这里插入图片描述



7、JAVA 中异常使用的注意事项

扩展: java中处理异常的9个注意事项

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值