栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java异常讲解及处理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java异常讲解及处理

这里写目录标题
  • 一级目录
    • 二级目录
      • 异常的定义

一级目录 二级目录 异常的定义

异常的定义:在Java语言中, 将程序执行中发生的不正常情况称为异常。而错误是系统错误,一般不需要开发人员处理(也无法处理),比如栈溢出或者内存不足。(开发过程中的语法错误和逻辑错误不是异常,也不是我们分类中的错误,是你的 错觉 哈哈)

异常的认知:在Java中,异常被定义为类,异常相关的类被称作异常类。当程序发生异常时,会抛出对应异常类的对象,该对象承载了异常信息,我们就能在显示框中看到诸如 NullPointerException, NoSuchElementException, IndexOutOfBoundsException 这些异常。

异常的体系:异常类,是由继承构成的,最上层是java.lang.Throwable。
下属两大子类,
1️⃣ java.lang.Error: Java虚拟机无法解决的严重问题。 如: JVM系统内部错误、 资源耗尽等严重情况。 例如:StackOverflowError和OutOfMemoryError。 这类错误一般不编写针对性的代码进行处理。

2️⃣ java.lang.Exception: 它出现的原因就是诸如 空指针访问,试图读取不存在的文件,数组索引越界等。 这类问题可以通过使用针对性的代码进行处理。

上面提到的 java.lang.Error ,这里不做过多说明。我们主要讲 写代码常遇到的 异常,也就是Exception ,Exception 又分为两类:
编译时异常(checked),编译时可能发生的异常,除了下面RuntimeException的子类,其他的异常都属于编译时异常。

运行时异常(unchecked/RuntimeException),编译时无异常,运行时发生的异常。

这里用图来展示它们之间的关系

里面涉及到一个概念,叫受检异常和非受检异常。其实受检异常就是编译异常,非受检异常就是运行时异常,这两个词应该很好理解。

常见运行时异常举例
1,NullPointerException

int[] arr = null;
System.out.println(arr[0]); // 数组空指针异常 

String str = null;
System.out.println(str.charAt(0)); // 字符串空指针异常 

2,NullPointerException

int[] arr = new int[10];
System.out.println(arr[10]); 	  	// 数组角标越界 ArrayIndexOutOfBoundsException

String str = "abc";
System.out.println(str.charAt(-1)); // 字符串角标越界 StringIndexOutOfBoundsException

3,ClassCastException

Father sonA = new SonA();
SonB sonB = (Sonb)sonA;  	// 类型转换异常 

Object obj = new Date();
String str = (String)obj; 	// 类型转换异常 

4,NumberFormatException

public void test2(){
    String str =  "abc";
    Integer.parseInt(str);  // 数字格式异常 
}

5,InputMismatchExcepton

Scanner scan = new Scanner(System.in);
int num = Scanner.nextInt();    // 输入非数字时,则会出现输入不匹配异常 

6,ArithmeticException

int a = 10;
int b = 0;   // 不能除0
System.out.println(a / b);  // 算数异常

异常的处理

有小伙伴可能会想,异常不都是程序发现并抛出的吗,那我们能干啥。嘿嘿,对于一般人,这个确实无解,但咱们程序猿可是无所不能的啊,当然有办法处理。
我们知道程序执行过程中,一旦出现异常,执行就会停止,后面的代码就不会再执行,这是因为我们没有处理,程序遇到异常就会交给JVM,它就会终止程序,那么如果我们告诉了它遇到这个异常,该干什么,它就不会中断执行。
我们要主动处理异常,就要提前预设会出现什么异常,以及出现异常后显示什么。

异常处理的方式:try-catch-finally 和 throws
使用方式如下:

try {
  // 可能出现异常的代码段
} catch(异常类型1 变量名1) {  // 也可以同时定义多个,但不推荐
  // 处理异常的方式1
} catch(异常类型2 变量名2) {
  // 处理异常的方式2
} catch(异常类型3 变量名3) {
  // 处理异常的方式3
}
...
finally {
    // 一定会执行的代码
}


在上述语法中, try catch是必须要有的,try负责运行可能出现异常的代码段,catch负责捕获相应的异常,如果没有捕获到,程序就交给JVM。 finally 是一个可选的部分,但是如果加上它,它里面的内容是无条件执行的。
关于catch使用的易错点,如果用catch写了多个异常,并且这些异常之间构成父子类,那么最上面一定要是子类。 道理很简单,父类包含的异常种类最多,如果把父类放上面,那么发现的所有异常都被父类通吃了,那么捕获异常所提示的信息就没有价值,不利于快速处理异常。

这个时候,有小伙伴又有疑问了,你说的try,catch,finally,我大概懂了,可是你不是还提了个 throws嘛,它怎么用啊,真是爱动脑筋的聪明鬼,好,那我们就讲一下它们的实战用法。

  public static void func2 throws NullPointerException() {
        int[] a = new int[]{};
        for (int i = 0; i < 5; i++) {
            a[i] = i;
            if (i == 4) {
            a[11] == 10;//由于没有11下标,所以一定会报空指针异常
            }
        }
    }

    public static void main(String[] args) {
        try{func2();
        }catch (NulException e){
            System.out.println("空指针异常");//这里输入信息,程序执行到这里,就会给出有关这个异常的信息,并且不会中断
        }
      }
    

结合上面这个例子,小伙伴们应该就懂了,throws 像一个岗哨,它在可能出现异常相关异常的方法前面声明这个异常,那么后续在调用这个方法执行时,就必须用 try catch来捕获,并给出处理方式,这样程序即使遇到异常,也能执行下去而不会中断。

除此而外,catch中还有两个方法可以使用,方便我们在后续代码开发中,及时发现问题,减轻工作量。
getMessage() : 返回值是String,主要作用是打印错误代码

printStackTrace(): 返回值类型是void ,主要作用是打印异常类型

还有说明的一点是,在实际生活中,遇到异常的场景不一样,同样的异常处理方式也不同,例如 和钱相关的场景,出现异常就属于比较严重的异常这个时候,就应该让程序直接崩溃掉。 而对于产生后果不严重的异常,就记日志或者监控报警并通知程序猿后期处理。

异常种类见了这么多个,但是有些伙计觉得有点不高兴,因为束缚了他的自由,不能让他大展才华,哈哈,那能不能自己定义异常呢,当然可以,那我们说一下怎么做到。

自定义异常

要注意一下几点,
1,自定义的类必须继承于现有的异常结构:通常继承于RuntimeException 和Exception (继承这个默认受查异常)
2,提供无参和一参的构造方法
如下

//自定义异常
class MyException extends RuntimeException{
    public MyException(){
        super();
    }
    public MyException(String message){
        super(message);
    }
}

//使用举例
 //异常
    public static void func() throws RuntimeException,NullPointerException{
        int a= 10;
        if (a == 10){
            throw new RuntimeException("a==10");
        }
    }

    public static void main10(String[] args) {
        try{
            func();
        }catch (RuntimeException e){
            System.out.println("抛出了一个异常!");
        }

    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/298938.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号