广告
返回顶部
首页 > 资讯 > 精选 >Java中Exception异常机制的原理
  • 579
分享到

Java中Exception异常机制的原理

2023-06-15 07:06:20 579人浏览 八月长安
摘要

本篇文章给大家分享的是有关Java中Exception异常机制的原理,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Error与Exception的区别与相同点:Error是严重

本篇文章给大家分享的是有关Java中Exception异常机制的原理,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

Error与Exception的区别与相同点:

  • Error是严重的错误,并非异常,错误是无法通过编码解决的。

  • Exception是异常,异常则是可以通过编码解决的。

Error与Exception的相同点:

  • Error与Exception类都是Throwable的子类

Exception类是所有异常的超类。

Java所有的异常在寻找父类的时候最终都能找到Exception类。

异常的分类

java.lang.Exception类是所有异常的超类,主要分为以下两种:

RuntimeException-运行时异常,也叫作非检测性异常.

lOException和其它异常-其它异常,也叫作检测性异常,所谓检测性异常就是指在编译阶段都能被编译器检测出来的异常。
其中RuntimeException类的主要子类︰ArithmeticException类-算术异常,ArraylndexOutOfBoundsException类-数组下标越界异常,NullPointerException-空指针异常,ClassCastException-类型转换异常,NumberEORMatException-数字格式异常注意:
当程序执行过程中发生异常但又没有手动处理时,则由Java虚拟机采用默认方式处理异常,而默认处理方式就是︰打印异常的名称、异常发生的原因、异常发生的位置以及终止程序。

二、关于RuntimeException

非检测性异常

package com.sinsy.exception;public class ExceptionTest {    public static void main(String[] args) {        // 非检测性异常 : Exception in thread "main" java.lang.ArithmeticException: / by zero JVM无法检测        System.out.println(5 / 0);        //检测型异常        Thread.sleep(3000);    }}

Java中Exception异常机制的原理

RuntimeException的主要子类有:

  • ArithmeticException–算数异常

  • ArrayIndexOutOfBoundsException–数组下标越界异常

  • NullPointerException–空指针异常

  • ClassCastException–类型转换异常

  • NumberFormatException–数字格式异常

下面通过代码来对异常做出解释:

Java中Exception异常机制的原理

为了让所有的异常都能正常的显示出来,我这里对每一种异常使用多线程来打印输出:

package com.sinsy.exception;public class ExceptionTest {    public static void main(String[] args) throws Exception {        // 非检测性异常 : Exception in thread "main" java.lang.ArithmeticException: / by zero jvm无法检测        // System.out.println(5 / 0);        //检测型异常        //Thread.sleep(3000);        exceptionTest();    }    public static void exceptionTest(){       new Thread(new Runnable() {           @Override           public void run() {               //第一种 数组下标越界异常               int arr[] = new int[5];               System.out.println(arr[5]);           }       }).start();        new Thread(new Runnable() {            @Override            public void run() {                //算数异常                int a = 1;                int b = 0;                System.out.println(a/b);            }        }).start();        new Thread(new Runnable() {            @Override            public void run() {                //空指针异常                String abc = null;                System.out.println(abc.length());            }        }).start();        new Thread(new Runnable() {            @Override            public void run() {                //类型转换异常                Exception exception = new Exception();                InterruptedException interruptedException =(InterruptedException) exception;            }        }).start();        new Thread(new Runnable() {            @Override            public void run() {                //数字格式异常                String ad = "1234a";                System.out.println(Integer.parseInt(ad));            }        }).start();    }}

运行之后的结果为:很清晰的看见,每一个线程代表着一种异常。

Java中Exception异常机制的原理

通过编码对各种异常进行处理之后,结果为:

public static void exceptionModifyTest(){    new Thread(() -> {        //第一种 数组下标越界异常        int arr[] = new int[5];        if (arr.length>5){        System.out.println(arr[5]);        }        System.out.println("下标越界异常已经规避");    }).start();    new Thread(new Runnable() {        @Override        public void run() {            //算数异常        int a = 1;        int b = 0;        if (0!=b){        System.out.println(a/b);        }            System.out.println("算术异常已经规避");        }    }).start();    new Thread(() -> {        //空指针异常        String abc = null;        if (null!=abc) {            System.out.println(abc.length());        }        System.out.println("空指针异常已经规避");    }).start();    new Thread(() -> {        //类型转换异常        Exception exception = new Exception();        if (exception instanceof  InterruptedException) {            InterruptedException interruptedException = (InterruptedException) exception;        }        System.out.println("类型转换异常已经规避");    }).start();    new Thread(() -> {        //数字格式异常        String ad = "1234a";        //字符串类型的数据做筛选一般选择正则表达式做第一选择        if (ad.matches("\\d+")){        System.out.println(Integer.parseInt(ad));        }        System.out.println("数字格式异常已避免");    }).start();}

运行结果为:

Java中Exception异常机制的原理

三、异常的避免

异常的避免其实上文已经凸显出来了结局方案,就是在可能出现异常的地方进行if判断处理,提前预判异常,然后对可能出现的异常跳过处理。

异常的避免(使用If-else)可能会导致大量的代码冗余,导致代码的沉积度过大,变得臃肿,可读性比较差。

四、异常的捕获

异常的捕获使用try{}catch{}来进行捕获

捕获不了的我们对其进行抛出

五、异常的抛出(异常的转移)

异常抛出抛给谁呢?当然是异常的捕获者。

异常抛出的时候需要注意一点,抛出的异常之间有父子类继承关系的,如果跑的异常包含多个,那么我们可以选择抛出异常最大的父类,直接可以抛出所有异常,这样节省了代码,但同时也对代码的可读性造成了一定的影响,让修改者无法直接得知此代码在使用过程中会出现什么样的异常。

基本概念

在某些特殊情况下有些异常不能处理或者不便于处理时,就可以将该异常转秘给该方法的调用者,这种方法就叫异常的抛出,本质上其实是异常的转移。方法执行时出现异常,则底层生成一个异常类对象抛出,此时异常代码后续的代码就不再执行。

语法格式

访问权限返回值类型方法名称(形参列表) throws异常类型1,异常类型2…{方法体;}如︰
public void show() throws lOExceptiont

方法重写的原则

a.要求方法名相同、参数列表相同以及返回值类型相同,从jdk1.5开始支持返回子类类型;b.要求方法的访问权限不能变小,可以相同或者变大;
c.要求方法不能抛出更大的异常;

注意

子类重写的方法不能抛出更大的异常、不能抛出平级不一样的异常,但可以抛出一样的异常、更小的异常以及不抛出异常。一定注意!!!!!!!!!!若父类中被重写的方法没有抛出异常时,则子类中重写的方法只能进行异常的捕获。不建议在Main方法中抛出异常,JVM需要执行的任务有很多,如果此时将大量的异常工作交给他来做,那么会影响JVMd额执行效率

异常的常规处理

对于常见的异常,通常对不同类型的异常有着不同的处理方法.

(1)如果父类方法抛出了异常,子类不能抛出比父类更大的异常,只能抛出与父类所抛异常类子类的异常,特殊情况可不抛出任何异常。

  • 父类抛出InterruptedException与IOException,子类只抛出InterruptedException,不抛出IOException

package com.sinsy.test;import java.io.FileInputStream;import java.io.IOException;public class ThrowExceptionFather {    public  void show() throws IOException, InterruptedException {        Thread.sleep(100);        System.out.println("hehehe");        FileInputStream fileInputStream =new FileInputStream("");        fileInputStream.close();    }}package com.sinsy.test;public class ThrowExceptionTest extends ThrowExceptionFather{    @Override    public void show() throws InterruptedException {        Thread.sleep(20);    }}
  • 父类的原始方法只抛出IOExeption,而子类在重写该方法的时候抛出父类中没有的异常,并且该异常与父类所抛异常并非同属某一类的子类,也就是说子类所抛出的异常与父类所抛出的异常并不是同一级。

package com.sinsy.test;import java.io.FileInputStream;import java.io.IOException;public class ThrowExceptionFather {    public  void show() throws IOException {        FileInputStream fileInputStream =new FileInputStream("");        fileInputStream.close();    }}package com.sinsy.test;public class ThrowExceptionTest extends ThrowExceptionFather{    @Override    public void show() throws InterruptedException {        Thread.sleep(20);    }}

此时代码报错,证明子类无法抛出与父类非同级关系的异常:

Java中Exception异常机制的原理

  • 父类只抛出一个异常,子类抛出与父类所抛异常同级但不同的异常:如下代码:子类抛出了一个与父类方法中同级别的异常但父类并未抛出该异常,此时代码报错:证明子类不可抛出与父类同级别的异常:(ClassNotLoadedException与IOException属于同一级别)

package com.sinsy.test;import com.sun.jdi.ClassNotLoadedException;import java.io.FileInputStream;import java.io.IOException;public class ThrowExceptionFather {    public  void show() throws IOException {        FileInputStream fileInputStream =new FileInputStream("");        fileInputStream.close();    }}package com.sinsy.test;import com.sun.jdi.ClassNotLoadedException;public class ThrowExceptionTest extends ThrowExceptionFather{    @Override    public void show() throws ClassNotLoadedException {    }}

Java中Exception异常机制的原理

但是子类可以抛出一个是父类所抛异常类的子类的异常:

Java中Exception异常机制的原理

通过对比IOException的简单继承关系我们可以选择一个IOException的子类,让继承了ThrowExceptionFather的子类在方法重写的时候去抛出该异常,如下代码:

package com.sinsy.test;import com.sun.jdi.ClassNotLoadedException;import java.NIO.file.FileSystemException;public class ThrowExceptionTest extends ThrowExceptionFather{    @Override    public void show() throws FileSystemException {    }}

此时未报错:

Java中Exception异常机制的原理

证明,子类可以抛出父类所抛异常类子类的异常。

因此,总结一句话就是:子类继承父类后,在重写父类方法的时候,如果父类中原有方法抛出了异常,那么子类不能抛出比父类所抛异常大的异常,只能抛出属于父类所抛异常类的子类的异常。

(2)若一个方法内部以递进式的方法分别调用了好几个其他的方法,则建议这些方法将异常逐层抛出,然后再统一处理。如下代码所示。

package com.sinsy.test;public class DiGonThrow {    public static void yu() {        try {            yu1();        } catch (Exception e) {            e.printStackTrace();        }    }    public static void yu1() throws Exception {        yu2();    }    public static void yu2() throws Exception {        yu3();    }    public static void yu3() throws Exception {        yu4();    }    public static void yu4() throws Exception {      yu5();    }    public static void yu5()throws Exception{        System.out.println(1);    }    public static void main(String[] args){        yu();    }}

将异常抛至最顶层的时候,此时做最后的 try-catch 处理。

(3)如果父类中被重写的方法没有抛出异常的时候,则子类中重写的方法只能进行异常的捕获处理。

//父类代码package com.sinsy.test;public class ThrowExceptionFather {    public  void show(){    }}//子类代码package com.sinsy.test;import java.io.FileInputStream;import java.io.IOException;public class ThrowExceptionTest extends ThrowExceptionFather{    @Override    public void show() {        FileInputStream fileInputStream =new FileInputStream("");        fileInputStream.close();    }}

若此时子类抛出异常,则会出现以下警示:

Method ‘show' is inherited.Do you want to add exceptions to method signatures in the whole method hierarchy?意思就是在说,方法‘Show'是继承的。要在整个方法层次结构中向方法签名添加异常吗?如果添加了之后,则父类中过就会抛出此异常!

Java中Exception异常机制的原理

六、自定义异常

基本概念

当需要在程序中表达年龄不合理的情况时,而Java官方又没有提供这种针对性的异常,此时就需要程序员自定义异常加以描述。

实现流程

a.自定义xxxException异常类继承Exception类或者其子类。
b.提供两个版本的构造方法,一个是在·无参构造方法,另外一个是字符电作为参数的构造方法。

异常的产生

throw new异常类型(实参);如∶throw new AgeException("年龄不合理!!! ");Java采用的异常处理机制,是将异常处理的程序代码集中在一起,与正常的程序代码分开**,使得程序简洁、优雅,并易于维护。**

自定义Exception异常类

要想实现自定义Exception异常类,我们需要写一个Exception的异常类去继承Exception类,实现无参构造方法以及有参数构造方法。

package com.sinsy.exception;public class AgeException extends Exception{        static final long serialVersionUID = -3387516993124229948L;        public AgeException() {    }        public AgeException(String message) {        super(message);    }}
  • 自定义Exception异常类的使用:

(1)首先确定应用场景为:用户个人信息的封装中,对成员属性的封装的时候对成员属性的设置出现异常:

package com.sinsy.bean;import com.sinsy.exception.AgeException;import java.util.Objects;public class Person {    private String name;    private String sex;    private int age;    public Person() {    }    public Person(String name, String sex, int age) {        this.name = name;        this.sex = sex;        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getSex() {        return sex;    }    public void setSex(String sex) {        this.sex = sex;    }    public int getAge() {        return age;    }    public void setAge(int age) throws AgeException {        if (age<0){            throw new AgeException("年龄设置错误哦!请稍后重试!");        }else{            this.age = age;        }    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Person person = (Person) o;        return age == person.age && Objects.equals(name, person.name) && Objects.equals(sex, person.sex);    }    @Override    public int hashCode() {        return Objects.hash(name, sex, age);    }    @Override    public String toString() {        return "Person{" +                "name='" + name + '\'' +                ", sex='" + sex + '\'' +                ", age=" + age +                '}';    }}

(2)确定引用场景之后,我们创建Test测试方法对目标用例进行简单测试:

package com.sinsy.test;import com.sinsy.bean.Person;import com.sinsy.exception.AgeException;public class PersonException {    public static void main(String[] args) {        Person person = new Person("二狗子");        try {            person.setAge(-12);        }catch (AgeException ageException){            ageException.printStackTrace();        }        System.out.println("执行完毕");    }}

测试结果如下:

Java中Exception异常机制的原理

这表明,AgeException的异常类使用正确,正确的打印出来了错误提示信息,这里的错误提示信息是自己自定义的,也就是你在调用AgeException类的时候自己输入的异常提示信息。这就是调用了AgeExceptiuon类的默认含参数的构造方法。

注意含有异常处理的代码执行顺序:

在遇到异常的时候我们需要根据异常出现的具体应用场景作相应的处理,如果是重写父类的继承下来的方法,我们在对方法进行重写的时候,我们需要注意,如果父类的原始方法并没有抛出异常,在子类中重写父类的方法是不需要抛出异常的,否则则会报错,而在处理异常的时候,我们更需要关注的是异常出现的位置以及时机。如果异常出现在可预测区域,则主动应该抛出对应可能会出现的异常,让代码安全的执行,不产生额外的错误。其二,在处理异常的时候,如果是递进式抛出异常,在最顶层的时候一定要try-catch处理异常,不可再向上抛出,如果抛给虚拟机来处理,那么则会响应JVM的执行效率。其三,当处理异常的时候,如果我们遇到与异常耦合度不高的业务需要执行的时候,我们可以在finally中编写与异常无耦合度的代码,确保必要的有业务能正常执行。

处理异常的时候由于finally与try-catch的关系,有时候会打乱原有代码的执行顺序,也会间接影响业务的执行:比如以下处理方法的不同导致在业务最后的结果完全不一致。代码如下

package com.sinsy.test;import com.sinsy.bean.Person;import com.sinsy.exception.AgeException;public class PersonException {    public static void main(String[] args) {        Person person = new Person("二狗子");        //注意我这里的处理异常的方式方法: 是在最顶层拿到异常之后直接当场做的处理,        try {            person.setAge(-12);        }catch (AgeException ageException){            //这里就是处理 直接将异常打印输出            ageException.printStackTrace();        }        System.out.println("执行完毕");    }}

处理之后的结果为:

Java中Exception异常机制的原理

**而如果我们将代码做一个简单的修改:**在设置年龄的2时候我们不对错误年龄进行抛出异常处理而是直接就地处理。则会怎么样呢?为了让效果更加明显,我们将SetAge的方法修改完之后我们再继续将测试方法中测试用例做一个简单的更改:

public void setAge(int age) {    if (age<0){       try {           throw new AgeException("年龄设置错误哦!请稍后重试!");       }catch (AgeException ageException){           ageException.printStackTrace();       }    }else{        this.age = age;    }}//测试方法:package com.sinsy.test;import com.sinsy.bean.Person;import com.sinsy.exception.AgeException;public class PersonException {    public static void main(String[] args) {        Person person = new Person("二狗子","男");        //注意我这里的处理异常的方式方法: 是在最顶层拿到异常之后直接当场做的处理,        person.setAge(-12);        System.out.println(person);    }}

最后的处理结果:

Java中Exception异常机制的原理

以上就是Java中Exception异常机制的原理,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网精选频道。

--结束END--

本文标题: Java中Exception异常机制的原理

本文链接: https://www.lsjlt.com/news/278675.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java中Exception异常机制的原理
    本篇文章给大家分享的是有关Java中Exception异常机制的原理,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Error与Exception的区别与相同点:Error是严重...
    99+
    2023-06-15
  • 详解Java的Exception异常机制
    目录一、前言二、关于RuntimeException三、异常的避免四、异常的捕获五、异常的抛出(异常的转移)六、自定义异常一、前言 在Java中,我们在执行代码的过程中难免会遇到错误...
    99+
    2022-11-12
  • Java 异常机制Exception和自定义异常
    目录异常机制异常体系结构异常的捕获与抛出自定义异常异常机制 异常:就是不符合实际需求,在实际中可能不存在也可能不满足实际,所以出现的问题称之为异常。 异常的三种类型: 检查性异常:用...
    99+
    2022-11-13
  • 解析PHP中Exception异常机制
    异常的基本使用 当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块。 如果异常没有被捕获,而且又没用使用 set_exception_handl...
    99+
    2022-11-12
  • java中异常处理机制的原理是什么
    Java中的异常处理机制是基于异常类的继承关系和异常处理代码块的机制。当程序发生异常时,会抛出一个异常对象,该异常对象会沿着调用链向...
    99+
    2023-08-31
    java
  • PHP中Exception异常机制的示例分析
    这篇文章将为大家详细讲解有关PHP中Exception异常机制的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。异常的基本使用当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 &qu...
    99+
    2023-06-20
  • java异常处理机制原理是什么
    Java异常处理机制的原理是基于异常(Exception)的概念。在Java中,异常是指在程序运行过程中发生的错误或异常情况。当代码...
    99+
    2023-09-16
    java
  • Java异常的处理机制
    图片解析: 1.生成字节码文件的过程可能产生编译时异常(checked),由字节码文件到在内存中加载、运行类此过程可能产生运行时异常(unchecked), 2.JAVA程序在执行...
    99+
    2022-11-12
  • Java的异常处理机制
    本篇内容介绍了“Java的异常处理机制”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java 异常处理异常是程序中的一些错误,但并不是所有的...
    99+
    2023-06-02
  • Java详细讲解异常Exception的处理
    目录异常介绍常见的运行时异常1.空指针异常2.数学运算异常3.数组下标越界异常4.类型转换异常5.数字格式不正确异常异常处理流程异常介绍 基本概念 程序执行中发生的不正常情况称为异常...
    99+
    2022-11-13
  • 【JAVA 异常处理机制】
    文章目录 前言1.java异常处理机制2.try-catch3.finally块4.自动关闭特性5.throw关键字6.throws关键字7.throws的重写规则8.异常分类9.异常API10.自定义异常总结: 前言 在Ja...
    99+
    2023-08-23
    java 开发语言 学习 intellij idea
  • JAVA中的深情哥-Exception(异常)-上
    文章目录 目录 文章目录 前言 一,Exception的起源  二,异常类  三,自定义异常 总结 前言 大家好,我是最爱吃兽奶,今天给大家介绍一下java中的深情哥 - Exception 秋风依依秋水寒,一点离愁两黯然;今生默默唯轻舞...
    99+
    2023-09-07
    开发语言 java
  • PHP异常机制的流程及原理
    本篇内容介绍了“PHP异常机制的流程及原理”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!PHP的异常机制的原理是什么?在PHP每一个可独立执...
    99+
    2023-06-17
  • java异常处理机制原理和应用的示例分析
    这篇文章主要介绍了java异常处理机制原理和应用的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、Java异常简介大家对trycatch可能并不陌生,也都使用的非常...
    99+
    2023-06-29
  • Java 详解异常的处理机制
    目录1.异常概述与异常体系结构1.1异常概述1.2运行时异常与编译时异常1.3异常体系结构2.常见异常1.ArrayIndexOutOfBoundsException2.NullPo...
    99+
    2022-11-12
  • Java中的异常处理机制介绍(非常全面!)
    目录异常处理机制编译时异常处理机制异常处理方式一异常处理方式二异常处理方式三运行时异常处理机制总结异常处理机制 异常的默认处理流程如下: 默认会在出现异常的代码那里自动的创建一个异常...
    99+
    2023-01-18
    Java异常处理机制原理 java中包含异常处理机制 java异常处理方式两种
  • Java中异常处理机制的示例分析
    这篇文章给大家分享的是有关Java中异常处理机制的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。  你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能...
    99+
    2023-06-03
  • Java 中的异常处理机制详情介绍
    目录介绍 Java 中的异常介绍 Error介绍 ExceptionJava 异常类的结构如何处理函数抛出的异常吞掉 or 抛出受检异常 or 非受检异常处理异常的原则尽量不要捕获通...
    99+
    2022-11-13
  • Java异常处理机制深入理解
    目录1.初识异常2.异常的基本用法异常处理流程3.为什么要使用异常?异常应只用于异常的情况4. 异常的种类 4.1 受查异常解决方案:4.2非受查异常5.如何使用异常避免不...
    99+
    2022-11-13
  • Java SpringMVC异常处理机制详解
    目录异常处理的思路测试环境准备异常处理两种方式方式一:简单异常处理器方式二:自定义异常处理器总结异常处理的思路 测试环境准备 首先写一个DemoController控制层的类作为测...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作