1.概述
在 Java 中,所有的异常都有一个共同的祖先java.lang包中的 Throwable类。
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
比如说,你的代码少了一个分号,那么运行出来结果是提示是错误java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出java.lang.ArithmeticException的异常。
异常发生的原因有很多,通常包含以下几大类:
- 用户输入了非法数据。
- 要打开的文件不存在。
- 网络通信时连接中断,或者JVM内存溢出。
这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。-
2.分类
throwable: 有两个重要的子类:Exception(异常)和 Error(错误) ;二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Exception包含检查性异常和运行时异常。
检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
Error中是是程序无法处理的错误,表示运行应用程序中较严重问题。它们在Java程序处理的范畴之外。
错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
3.说明
Java根据各个类库也定义了一些其他的异常,下面的表中列出了Java的运行时异常。
下面的表中列出了Java定义在java.lang包中的检查性异常类。
java中常见的error有如下:
当JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError 。
4.异常方法
下面的列表是Throwable 类的主要方法:
5.异常处理
(1)单重异常处理
使用try和catch关键字可以捕获异常。try/catch代码块放在异常可能发生的地方。
try/catch代码块中的代码称为保护代码,使用 try/catch的语法如下:
try
{
// 程序代码
}catch(ExceptionName e1)
{
//Catch 块
}
Catch语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try后面的catch块就会被检查。
如果发生的异常包含在catch块中,异常会被传递到该catch块,这和传递一个参数到方法是一样。然后执行catch块的代码。对异常进行一些处理
示例:
public class ExcepTest{
public static void main(String args[]){
try{
int a[] = new int[2];
System.out.println("Access element three :" + a[3]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Exception thrown :" + e);
}
System.out.println("Out of the block");
}
}
运行结果:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block
(2)多重异常处理
一个try代码块后面跟随多个catch代码块的情况就叫多重捕获。
多重捕获块的语法如下所示:
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}
上面的代码段包含了3个catch块。
可以在ry语句后面添加任意数量的catch块。
如果保护代码中发生异常,异常被抛给第一个catch块。
如果抛出异常的数据类型与ExceptionType1匹配,它在这里就会被捕获。
如果不匹配,它会被传递给第二个catch块。
如此,直到异常被捕获或者通过所有的catch块。
(3)throws/throw关键字:
如果一个方法没有捕获一个检查性异常,那么该方法必须使用throws 关键字来声明。throws关键字放在方法签名的尾部。
也可以使用throw关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。
下面方法的声明抛出一个RemoteException异常:
import java.io.*;
public class className
{
public void deposit(double amount) throws RemoteException
{
// Method implementation
throw new RemoteException();
}
//Remainder of class definition
}
在开发中,经常会遇到一些业务error,这时候可以使用throw来抛出异常,当然这个异常可以进行自定义。
一个方法可以使用throws抛出多个异常,多个异常之间用逗号隔开。
(4)finally关键字
finally关键字用来创建在try代码块后面执行的代码块。
无论是否发生异常,finally代码块中的代码总会被执行。
在finally代码块中,可以运行清理类型等收尾善后性质的语句。
finally代码块出现在catch代码块最后,语法如下:
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}
示例:
public class ExcepTest{
public static void main(String args[]){
int a[] = new int[2];
try{
System.out.println("Access element three :" + a[3]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Exception thrown :" + e);
}
finally{
a[0] = 6;
System.out.println("First element value: " +a[0]);
System.out.println("The finally statement is executed");
}
}
}
运行结果:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed
注意下面事项:
- catch不能独立于try存在。
- 在try/catch后面添加finally块并非强制性要求的。
- try代码后不能既没catch块也没finally块。
- try, catch, finally块之间不能添加任何代码。
6.自定义异常
在Java中你可以自定义异常。编写自己的异常类时需要记住下面的几点。
- 所有异常都必须是Throwable的子类。
- 如果希望写一个检查性异常类,则需要继承Exception类。
- 如果你想写一个运行时异常类,那么需要继承RuntimeException 类。
示例1:
class MyException extends Exception{
}
一个异常类和其它任何类一样,包含有变量和方法。
示例2:
package com.ruoyi.common.core.exception;
/**
* 系统间调用异常
*
* @author linaibo
* @version 1.0
* Create by 2022/10/13 14:04
*/
public class HttpFailException extends RuntimeException {
private static final long serialVersionUID = 1L;
public HttpFailException(String msg) {
super(msg);
}
}
示例3:
package com.ruoyi.common.core.exception;
/**
* 业务异常
*
* @author ruoyi
*/
public final class ServiceException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 错误码
*/
private Integer code;
/**
* 错误提示
*/
private String message;
/**
* 错误明细,内部调试错误
*
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
*/
private String detailMessage;
/**
* 空构造方法,避免反序列化问题
*/
public ServiceException()
{
}
public ServiceException(String message)
{
this.message = message;
}
public ServiceException(String message, Integer code)
{
this.message = message;
this.code = code;
}
public String getDetailMessage()
{
return detailMessage;
}
public String getMessage()
{
return message;
}
public Integer getCode()
{
return code;
}
public ServiceException setMessage(String message)
{
this.message = message;
return this;
}
public ServiceException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
}