Java基础之异常处理
- 一、Java异常处理
- 二、捕捉异常
- 三、常见异常
- 四、自定义异常
- 4.1、throw关键字
- 注意事项:
- 4.2、throws关键字
- 关键点:
- 注意事项:
- 4.3、throw和throws的区别:
一、Java异常处理
异常机制可以使程序中的异常处理代码和正常业务代码分离。在程序设计和运行的过程中,发生错误是不可避免的。为此Java提供了异常的处理机制,来帮助程序员检查可能出现的错误。保证程序的可读性和可维护性。Java将异常封装到一个类中,出现错误时就会抛出异常,程序终止。
Error错误:一般是指与虚拟机相关的问题,如系统崩溃、JVM系统内部资源耗尽、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断。比如:StackOverflowError(栈溢出)和OOM(内存溢出)
Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:
- 空指针访问
- 试图读取不存在的文件
- 网络连接中断
- 数组角标越界
Error和Exception都有一个共同的根类是Throwable类,下表为常用的异常分类。
为了保证程序能正常的运行,我们需要对出现的异常错误进行及时的处理。在Java 的异常处理机制当中,当某个方法出现异常时,可以在该方法里进行捕捉,然后处理异常,也可以将异常向上抛出,交给该方法的调用者处理。
二、捕捉异常
Java语言的异常捕捉结构为:
try{// 可能产生异常错误的代码块
}catch( ExceptionTypeOne e){// 对异常 ExceptionTypeOne 的处理语句
}catch ( ExceptionTypeTwo e) {// 对ExceptionTypeTwo 的处理语句
}
...
finally { // 无论成功与否都会执行的代码块,一般用于关流// 资源回收语句块
}
语法解释:
①try语句是可能发生异常的部分
②catch用来捕捉异常代码,{}中为异常处理的语句。
getMessage() 获取异常信息,返回字符串。
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。 toString()给出异常的性质和类型
③finally为异常处理的最后一步,catch未被捕捉,finally也一定会执行。
主要做一些清理工作,如流的关闭,数据库连接的关闭等。
三、常见异常
Java常见异常如下表所示:
异常类 | 说明 |
---|---|
受检查异常(Checked Exception) | 受检异常是在编译时由编译器检查并强制要求程序员处理的异常 |
IOException | 输入/输出异常,包括文件读写错误 |
SQLException | 数据库访问异常 |
FileNotFoundException | 尝试访问不存在的文件 |
ParseException | 字符串解析异常,通常与日期和时间相关 |
非受检异常(Unchecked Exception) | 非受检异常是在运行时发生的异常,通常是由于程序逻辑错误或其他不可预测的因素引起的 |
NullPointerException | 尝试访问空对象引用 |
ArrayIndexOutBoundsException | 数组索引越界 |
ArithmeticException | 算术运算异常,如除以零 |
ClassCastException | 类型转换异常 |
lllegalArgumentException | 非法参数异常 |
lllegalStateException | 程序或环境处于不适当状态异常 |
四、自定义异常
自定义异常是指根据程序的需求和特定情境,程序员自己定义的异常类。这些异常类通常是通过继承 Java 中的异常类(通常是 Exception
或其子类)来创建的,以便提供更具体和可读性强的异常信息。
自定义异常类的结构如下:
public class CustomException extends Exception {// 构造方法public CustomException() {super();}public CustomException(String message) {super(message);}public CustomException(String message, Throwable cause) {super(message, cause);}// 可以添加自定义的方法或属性
}
上述代码中,CustomException
继承了 Exception
类,提供了几个构造方法,其中包含了不同的参数组合。这样的设计使得我们在抛出自定义异常时能够提供详细的异常信息,并且可以选择将原始异常(cause)连接到新的异常对象中,形成异常链。
代码示例:
public class CustomValidationException extends Exception {private String fieldName;public CustomValidationException(String fieldName, String message) {super(message);this.fieldName = fieldName;}public String getFieldName() {return fieldName;}
}
//这个自定义异常用于表示验证失败的情况,其中包含了字段名称和相应的错误信息。
4.1、throw关键字
-
抛出特定异常
throw new SomeException("This is a custom exception message");
SomeException
是一个自定义异常类,通过throw
关键字创建了该异常的一个实例,并传递了一个描述性的错误消息。 -
方法声明抛出异常
在方法的声明中,你可以使用
throws
关键字指定该方法可能抛出的异常类型。然后,在方法的实现中,你可以使用throw
关键字抛出这些异常。public void someMethod() throws SomeException {// some codeif (errorCondition) {throw new SomeException("Error message");}// more code }
在这个例子中,
someMethod
方法声明可能抛出SomeException
异常。在方法的实现中,如果满足某些条件,就会使用throw
抛出该异常。 -
抛出现有异常
你也可以使用
throw
关键字重新抛出当前上下文中已捕获的异常。这通常发生在catch
块中,当你希望在捕获异常后将其传递给上层调用者时使用。try {// some code that may throw an exception } catch (SomeException e) {// handle the exceptionthrow e; // rethrow the exception }
注意事项:
此外,throw必须写在方法体内部 ,抛出的对象必须是Exception 或者 Exception 的子类对象。如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理 如果抛出的是编译时异常,用户必须处理,否则无法通过编译 。异常一旦抛出,其后的代码就不会执行
4.2、throws关键字
在Java中,throws
是一个关键字,用于在方法签名中声明可能抛出的异常。当一个方法可能抛出某种类型的异常时,你可以使用 throws
关键字将这些异常列在方法的声明中,以告知调用方可能需要处理这些异常。
语法格式如下:
[(修饰符)] (返回类型) (方法名) ([参数列表]) [throws(异常类)]{...}public void doA(int a) throws Exception1,Exception3{......}void methodName() throws SomeException, AnotherException {// method implementation
}
在这个例子中,methodName
方法声明可能抛出 SomeException
和 AnotherException
这两种异常。调用方在调用这个方法时,必须要么处理这些异常,要么再次使用 throws
将这些异常传递给更高层次的调用。
关键点:
-
多个异常类型: 你可以在
throws
子句中列出多个异常类型,用逗号分隔。void myMethod() throws IOException, SQLException {// method implementation }
-
派生异常: 如果方法可能抛出某个异常的子类,你可以只声明父类异常,而不需要显式地声明所有可能的子类异常。
void myMethod() throws IOException {// method implementation }
-
RuntimeException: 对于运行时异常(RuntimeException)及其子类,你通常不需要在方法签名中使用
throws
关键字声明,因为它们是不受检查的异常,编译器不会强制你在调用这些方法时进行异常处理
注意事项:
- throws必须跟在方法的参数列表之后
- 声明的异常必须是 Exception 或者 Exception 的子类
4.3、throw和throws的区别:
throw | throws |
---|---|
语句抛出一个异常 | 方法可能抛出异常的声明。 |
用在方法体内,抛出的异常由方法体内的语句处理; | 方法函数头,抛出的异常由方法的调用者处理。 |
具体向外跑出的异常,是抛出来的一个异常实例 | 声明这个方法会抛出这个类型的异常,调用者知道要捕获这个异常 |