在Java中使用方法覆盖处理异常

1. 异常处理概述

在Java中,任何代码都有可能发生异常,例如访问null对象、数组越界、除零、网络中断等等情况。如果异常一直没有被处理,程序就会崩溃。因此,Java中提供了异常处理机制来让开发者在运行时处理异常,保证程序的健壮性。

注意:异常处理是Java程序设计中极其重要的一部分,如果错误使用异常处理机制,可能会使程序的性能、可读性、可维护性大大下降。

2. 异常处理的两种方式

Java中采用了两种方式来处理异常:

2.1 抛出异常

抛出异常,即在可能出现异常的地方声明要抛出异常,并交给上层方法或调用者来处理。抛出异常使用throw关键字。抛出异常可以是Java中任何一个类的对象,不一定是{@link Throwable}子类或其子类的对象。一个方法可以抛出多种异常类型,但只能抛出{@link Throwable}或其子类异常。

public void writeFile(String path, String content) throws FileNotFoundException, IOException {

// 写文件的代码

}

2.2 捕获异常

捕获异常,即在代码中写出针对异常的处理逻辑。捕获异常使用try...catch...finally语句,try代码块中放置可能会抛出异常的代码,catch代码块中放置针对不同异常的处理逻辑,finally代码块中放置无论是否发生异常都需要执行的代码。

try {

// 可能会抛出异常的代码

} catch (FileNotFoundException e) {

// 针对FileNotFoundException的处理逻辑

} catch (IOException e) {

// 针对IOException的处理逻辑

} finally {

// 无论是否发生异常都需要执行的代码

}

3. 方法覆盖异常处理

当一个子类继承了一个父类后,如果父类中抛出了异常且子类中的方法覆盖了该方法,则子类中必须抛出与父类相同的异常,或者是它的子类型。

public class Father {

public void func() throws IOException {

// 抛出异常

}

}

public class Child extends Father {

public void func() throws FileNotFoundException {

// 抛出FileNotFoundException或其子类型

}

}

上面的代码表示,一个父类中有一个可能抛出{@link IOException}异常的方法,子类继承该父类,并覆盖了该方法,那么子类中的{@code func()}方法必须抛出{@link IOException}或其子类型的异常。

如果子类中的方法抛出的异常是父类方法抛出异常的子类,则编译器不会报错。如果子类中的方法抛出了父类方法中未声明的异常,则编译器会提示错误。

4. 示例

下面的示例演示了如何在父类和子类中抛出异常,并覆盖父类的方法。其中,父类中的方法声明要抛出{@link IOException}异常;子类中覆盖了该方法,并抛出了{@link FileNotFoundException}异常,编译没有出现错误。

public class ExceptionTest {

public static void main(String[] args) {

Father f = new Child();

try {

f.func();

} catch (IOException e) {

e.printStackTrace();

}

}

}

class Father {

public void func() throws IOException {

System.out.println("Father's func().");

throw new IOException("IOException in Father's func().");

}

}

class Child extends Father {

public void func() throws FileNotFoundException {

System.out.println("Child's func().");

throw new FileNotFoundException("FileNotFoundException in Child's func().");

}

}

程序的输出是:

Child's func().

java.io.FileNotFoundException: FileNotFoundException in Child's func().

at Child.func(ExceptionTest.java:23)

at ExceptionTest.main(ExceptionTest.java:7)

程序首先创建了一个Father类型的实例,将其赋值给f变量;然后调用{@code f.func()}方法,并在{@code try...catch}块中捕获有可能抛出的{@link IOException}异常。这个方法会调用Child的{@code func()}方法,将编译器处理异常机制转换为运行时处理异常机制,在运行时抛出异常。程序在catch代码块中打印了异常的堆栈信息。

后端开发标签