1:异常的概念?
在Java中,异常(Exception)是指程序执行过程中可能出现的不正常情况或错误。它是一个事件,它会干扰程序的正常执行流程,并可能导致程序出现错误或崩溃。
异常在Java中是以对象的形式表示的,这些对象是从java.lang.Throwable类或其子类派生而来。Throwable是异常类层次结构的根类,它有两个主要的子类:java.lang.Exception和java.lang.Error。
Exception(异常):java.lang.Exception是表示可检查异常的基类。可检查异常是指在编译时需要显式处理的异常。Exception类及其子类用于表示程序运行过程中可能出现的外部条件、错误或其他可恢复的情况。例如,文件未找到、网络连接中断、输入格式错误等。开发人员需要通过捕获或声明这些异常来确保在程序中进行适当的异常处理。
Error(错误):java.lang.Error是表示严重问题或系统级错误的基类。错误是指那些程序通常无法处理或恢复的情况,例如内存溢出、堆栈溢出、虚拟机错误等。与异常不同,错误不需要在程序中显式处理,因为它们通常表示了无法解决的问题。
异常在Java中通过抛出(throw)和捕获(catch)的方式进行处理。当程序执行到可能引发异常的代码时,可以使用throw语句手动抛出异常对象。然后,可以使用try-catch语句块来捕获异常,并在catch块中提供相应的异常处理逻辑。在catch块中,可以根据异常的类型执行适当的操作,如日志记录、错误报告或异常处理。如果异常没有在当前方法中被捕获处理,它将继续向上级调用栈传播,直到找到合适的异常处理代码或导致程序终止。
2:异常的体系结构
Throwable是异常类体系结构的根类。它是所有异常类的超类,直接或间接地派生了Error和Exception两个主要子类。
Error表示严重的问题或系统级错误,它们通常是由Java虚拟机(JVM)本身引起的,例如内存溢出、堆栈溢出等。程序通常无法恢复或处理这些错误。
Exception是表示可检查异常的基类。它包括两个主要的分支:
RuntimeException是运行时异常的基类,它表示程序内部错误或逻辑错误。这些异常通常是由编程错误引起的,例如空指针引用、除以零等。运行时异常在编译时不会被强制检查,因此可以选择捕获和处理它们,但也可以选择不处理。
Exception的其他子类表示其他可检查异常,例如输入/输出异常(IOException)、SQL异常(SQLException)等。这些异常在编译时会被强制检查,程序必须显式地处理它们,否则会导致编译错误。
3:常见的运行时异常有哪些
- NullPointerException - 空指针异常
- ClassCastException - 类转换异常
- IndexOutOfBoundsException - 下标越界异常
- ArithmeticException - 计算异常
- IllegalArgumentException - 非法参数异常
- NumberFormatException - 数字格式异常
- UnsupportedOperationException 操作不支持异常
- ArrayStoreException - 数据存储异常,操作数组时类型不一致
- BufferOverflowException - IO 操作时出现的缓冲区上溢异常
- NoSuchElementException - 元素不存在异常
- InputMismatchException - 输入类型不匹配异常
4:异常的捕获和处理
1异常声明throws
在Java中,使用throws
关键字可以在方法声明中指定该方法可能抛出的异常类型。通过使用throws
关键字,方法可以将异常的处理责任委托给调用者,而不是在方法内部处理异常。
2try-catch捕获并处理
在Java中,可以使用try-catch
语句块来捕获和处理异常。try-catch
语句块允许我们在执行可能引发异常的代码时,捕获并处理异常,从而防止程序终止或产生不可预测的结果。
5:throw和throws的区别
1语法位置不同。throw用于函数内部,后面跟的是异常对象,而throws用于函数结尾,后面跟的是异常类,后面可以跟多个不同的异常类,表示抛出不同的异常
2关键字功能不同。throw用于抛出异常,并将问题立即抛出给上一级的调用者,
并且当throw执行到时,后面的其他语句不会执行。而throws只是用于声明异常,让调用者知道这里可能会出现问题,并提前处理异常发生情况,属于一种提前通知。
同时,他们两个也有相同点。那就是都是被动的方式(不主动处理)来处理异常,只是抛出异常,真正处理异常的往往是由调用他们的上层函数去捕获处理。
6:如何自定义异常
6.1 自定义异常类的规则
在Java中,可以通过创建自定义异常类来表示和处理特定的异常情况。以下是关于自定义异常类的一些规则:
自定义异常类应继承自Exception类或其子类。通常,如果自定义异常类表示非检查异常,则可以继承RuntimeException类或其子类。
自定义异常类应提供适当的构造方法。通常,至少应包含一个带有异常信息的构造方法,以便在抛出异常时传递详细信息。可以根据需要添加其他构造方法,以便传递更多的异常信息和原因。
自定义异常类可以添加自定义的方法和逻辑,以满足特定需求。例如,可以添加用于获取特定信息的方法或执行特定操作的方法。
自定义异常类的命名应具有描述性,并遵循Java的命名约定。通常,类名以Exception结尾是一种常见的命名约定,例如MyCustomException。
自定义异常类可以根据特定的异常情况进行层次化。您可以创建自定义异常类的层次结构,通过继承关系来表示不同级别或类型的异常。这有助于更好地组织和处理不同类型的异常。
以下是一个示例,展示了一个自定义异常类的规则和示例代码:
在上述示例中,创建了一个名为MyCustomException的自定义异常类。该类继承自Exception类,并提供了多个构造方法,以便在抛出异常时传递不同的异常信息和原因。
6.2 自定义异常案例
这里实现一个用户登陆功能,在登录的时候对用户名和密码进行校验,登录和校验的逻辑如下:
在上述代码中,Login类包含了一个名为loginInfo的方法,该方法接受用户名和密码作为参数。在方法中,我们使用try-catch块来捕获可能抛出的UserNameErrorException和PasswordException异常。
在try块中,我们检查输入的用户名和密码是否与预定义的用户名和密码匹配。如果不匹配,我们抛出相应的异常,即UserNameErrorException或PasswordException。如果用户名和密码都正确,将输出"登录成功"。
在catch块中,我们捕获并处理可能抛出的异常。通过调用printStackTrace()方法,异常的堆栈跟踪信息将被打印出来,以便进行错误排查和调试。
在main方法中,创建一个Login对象并调用loginInfo方法来进行登录测试。在本例中,我们传递了正确的用户名和密码,因此输出将是"登录成功"。如果用户名或密码错误,将在控制台上打印异常的堆栈跟踪信息。
自定义异常类 PasswordException 和 UserNameErrorException :
在上述代码中,PasswordException和UserNameErrorException类都继承自RuntimeException类,因此它们都是非检查异常。
这两个异常类提供了两个构造方法:
无参构造方法:调用父类RuntimeException的无参构造方法,用于创建一个没有特定错误信息的异常对象。
带有字符串参数的构造方法:调用父类RuntimeException的带有字符串参数的构造方法,用于创建一个带有特定错误信息的异常对象。
通过定义这两个自定义异常类,可以在需要时抛出PasswordException和UserNameErrorException异常,并传递适当的错误信息。这样可以更好地处理与密码和用户名相关的异常情况,并提供有关错误的详细信息。