7.Java异常知识总结(声明、抛出、捕获异常)
7.1异常定义
- 在程序运行过程中,如果JVM检测出一个不可能执行的操作时,就会出现运行时错误(runtime error)。在Java中,运行时错误会作为异常抛出。
- 异常就是一种对象,表示阻止正常进行程序执行的错误或情况。如果异常没有被处理,那么程序将会非正常终止。
7.2异常类继承层次(与错误区分)
- 异常是对象,异常封装成类Exception,所有的异常都直接或间接继承自Throwable类。
- Throwable类有两个直接的子类,Error和Exception。
- 可以通过继承Exception或Exception的子类来创建自己的异常类。
- Exception是程序可以恢复的异常。如除零异常、空指针访问、网络连接中断、读取不存在的文件等。
- Exception类分为受检查异常和运行时异常
- 受检查异常(必检异常):是除RuntimeException以外的异常,特点是编译器会强制程序员检查并通过try-catch块处理它们,或在方法头进行声明。如处理数据库异常的SQLException,处理读写异常的IOException
- 运行时异常(免检异常):是继承RuntimeExceptionl类的直接或间接类。编译器不检查这类异常是否进行了处理,也就是对于这类异常不捕获也不抛出,程序也可以编译通过。一旦运行时异常时就会导致程序的终止。如访问一个数组的越界元素,会抛出一个IndexOutofBoundsException异常。
7.3异常的处理模型
Java的异常处理模型基于三种操作:
- 声明一个异常
- 抛出一个异常或者捕获一个异常。
7.3.1抛出异常(throws)
(1)throws关键字
-
throws通常在方法首部的声明后抛出异常。
-
throws抛出的是可能发生的异常。(并不一定会发生这些异常)
-
当该方法被调用的时候必须捕获,或者也可以再次抛出异常,最终由Java虚拟机处理。
-
用来声明一个方法可能产生的所有异常(用,分隔), 不做任何处理而是将异常往上传,谁调用我我就抛给谁。
-
举例:
class MyAnimation{ public Image loadImage(String s) throws IOException{ ... } }
(2)throw关键字
-
throw关键字通常用在方法体中,并且抛出一个异常对象。
-
throw则是抛出了异常,执行throw则一定抛出了某种异常
-
只能抛出一个异常对象
-
有两种方式捕获。要么自己捕获异常 try-catch 代码块,要么是抛出一个异常(throws 异常)
-
举例:
String readData(Scanner in)throws EOFException{ while(...){ if(!in.hasNext())//遇到EOFException异常 if(n<len){ throw new EOFException(); }... } }
(3)小结
- throw抛出一个异常对象时需要由函数的上层调用处理这个异常,此时,可以通过try-catch(finally)代码块,也可以通过throws进行抛出。(一定要处理)
- throws抛出一个可能的异常时可以不对此异常进行处理。
7.3.2 捕获异常(try-catch-finally)
(1)try-catch-finally语句
try{
//需要被检测的异常代码
}catch(Exception e){
//异常处理,即处理异常的代码(打印异常信息并处理)
}finally{
//一定会被执行的代码(通常可以进行资源的清除工作)
}
(2)try-catch语句
try{
//需要被检测的异常代码
}catch(Exception e){
//异常处理,即处理异常的代码(打印异常信息并处理)
}
(3)try-finally语句
try{
//需要被检测的异常代码
}finally{
//一定会被执行的代码(通常可以进行资源的清除工作)
}
(4)多catch语句
try{
//需要被检测的异常代码
}catch(Exception e1){
//异常处理,即处理异常的代码(打印异常信息并处理)
}catch(IOException e2){
//异常处理,即处理异常的代码(打印异常信息并处理)
} //可以通过catch处理多个异常。
7.3.3举例
public class TestException {
//测试0
boolean testEx() throws Exception{
boolean res = true;
try{
res = testEx1();//执行
}catch (Exception e){
System.out.println("测试0,捕获异常");
res = false;
throw e;
}finally{
System.out.println("测试0, finally 最终返回的值 =" + res);
return res;
}
}
//测试1
boolean testEx1() throws Exception{
boolean res= true;
try{
res = testEx2();
if (!res){
return false;
}
return res;
}catch (Exception e){
System.out.println("测试1, catch捕获");
res = false;
throw e;
}finally{
System.out.println("测试1, finally最终返回值 =" + res);
return res;
}
}
//测试2
boolean testEx2() throws Exception{
boolean res = true;
try{
int b = 2;
int c;
for (int i = 2; i >= 0; i--){
c = b / i;
System.out.println("c="+c+"\ti=" + i);
}
return true;
}catch (Exception e){
System.out.println("测试2, catch捕获");
res = false;
throw e;
}finally{
System.out.println("测试2, finally最终值 =" + res);
return res;
}
}
}//借鉴Angel_Kitty的例子
7.4自定义异常
7.4.1自定义异常类
class CustomException extends Exception {
private String customMessage;
public CustomException(String message) {
super(message);
this.customMessage = message;
}
public String getCustomMessage() {
return customMessage;
}
}
7.4.2测试类—>并抛出自己的异常
class Example {
public static void main(String[] args) {
try {
// 模拟条件触发自定义异常抛出
int age = -1;
if (age < 0) {
throw new CustomException("年龄不能为负数");
}
} catch (CustomException e) {
System.out.println("捕获到自定义异常:" + e.getCustomMessage());
}
}
}