JAVA异常
什么是异常
异常是指中断程序正常执行的一个不确定的事件。当异常发生时,程序的正常执行流程就会被打断。一般情况下,程序都会有很多条语句,如果没有异常处理机制,前面的语句一旦出现了异常,后面的语句就没办法继续执行了
除此之外,异常处理机制可以保证我们向用户提供友好的提示信息,而不是程序原生的异常信息——用户根本理解不了。
抛出异常的原因
- 程序在试图打开一个不存在的文件;
- 程序遇到了网络连接问题;
- 用户输入了糟糕的数据;
- 程序在处理算术问题时没有考虑除数为 0 的情况;
- 。。。。
例如
public class Demo {
public static void main(String[] args) {
System.out.println(10/0);
}
}
这段代码在运行的时候抛出的异常信息如下所示:
Exception in thread "main" java.lang.ArithmeticException: / by zero at com.itwanger.s41.Demo.main(Demo.java:8)
Exception和Error的区别
error 为错误,exception 为异常,错误的等级明显比异常要高一些。
Error 的出现标志着程序遭遇到了无法挽回的严重问题,这类问题超出了Java异常处理机制常规处理的范畴,通常指示程序应当立即终止执行以避免进一步的不稳定或损害。例如,当发生OutOfMemoryError时,它明确指出了程序在运行时尝试使用的内存量已超出系统所能提供的极限,这是一个对程序运行构成根本性威胁的错误,其出现往往意味着程序无法继续稳定执行。
Exception 的发生则表明程序在执行过程中遇到了预期之内或可预测的问题,这类问题虽然打断了程序的正常流程,但通常可以通过编写异常处理代码(如try-catch块)来捕获并相应地处理,从而恢复程序的部分或全部功能,实现问题的有效控制和程序的继续运行。
还有一个RuntimeException运行时异常,它描述的是程序设计错误,例如,错误的类型转换、访问一个越界数组或数值错误。运行时异常通常是由 Java 虚拟机抛出的。RuntimeException 的任何子类都无需在 throws 子句中进行声明,指的就是这些问题不需要提前被预防
RuntimeException、Error 以及它们的子类都称为免检异(unchecked exception )。所有其他异常(编译时异常)都称为必检异常(checked exception), 意思是指编译器会强制程序员检査并通过 try- catch 块处理它们,或者在方法头进行声明
throw和throws
throw 关键字,用于主动地抛出异常,语法也非常简单,throw 关键字后跟上 new 关键字,以及异常的类型还有参数即可。
throw new ArithmeticException("Exception");
如果有多个方法并且会出现多种异常,就使用throws关键字,在方法签名上声明可能会抛出的异常,然后在调用该方法的地方使用 try-catch 进行处理。
public static void main(String args[]){
try {
myMethod1();
} catch (ArithmeticException e) {
// 算术异常
} catch (NullPointerException e) {
// 空指针异常
}
}
public static void myMethod1() throws ArithmeticException, NullPointerException{
// 方法签名上声明异常
}
总结
- throws 关键字用于声明异常,它的作用和 try-catch 相似;而 throw 关键字用于显式的抛出异常。
- throws 关键字后面跟的是异常的名字;而 throw 关键字后面跟的是异常的对象。
- throws 关键字出现在方法签名上,而 throw 关键字出现在方法体里。
- throws 关键字在声明异常的时候可以跟多个,用逗号隔开;而 throw 关键字每次只能抛出一个异常。
try-catch-finally
现在我们知道了如何声明一个异常以及如何抛出一个异常。当抛出一个异常时,可以在try-catch 块中捕获和处理它;
try语句块中:放的是可能出现问题的代码,尽量不要把不相关的代码放入到里面,否则会出现截断的问题。一个 try
块后面可以跟多个 catch
块,用来捕获不同类型的异常并做相应的处理,当 try 块中的某一行代码发生异常时,之后的代码就不再执行,而是会跳转到异常对应的 catch 块中执行。
try{
codeA
throw ...
codeB
}
catch语句块中:放的是出现问题并捕获后,处理问题的代码code,如果问题在try语句块中没有出现 则catch中不会运行。
catch(Exception e) {
code
}
//多个catch
catch(ArithmeticException | ArrayIndexOutOfBoundsException e)
finally语句块中:放的是不管问题异常是否产生 都要执行的代码code。
不执行finally的情况:死循环、System.exit()
finally{
code//关闭资源(IO 数据库 网络),结尾处理的一些工作
}
注意:如果一个 try 块后面跟了多个与之关联的 catch 块,那么应该把特定的异常放在前面,通用型的异常放在后面,不然编译器会提示错误。举例来说。
static void test() {
try {
//代码
} catch (ArithmeticException e) {
// 算术运算发生错误时跳转到这里
System.out.println("除数不能为零");
} catch (Exception e) {
// 通用型的异常意味着可以捕获所有的异常,它应该放在最后面,
System.out.println("异常发生了");
}
System.out.println("try-catch 之外的代码.");
}
一文彻底搞懂Java异常处理,YYDS | 二哥的Java进阶之路 (javabetter.cn)
原文链接:https://blog.youkuaiyun.com/m0_46316970/article/details/119898445