如何理解Java:方法重写的时候,抛出异常不能更多,可以更少。但是运行时异常可以在重写的时候抛出新的异常

在 Java 中,方法重写(Overriding)时,抛出异常的规则可以总结为:抛出的异常不能比父类方法多,只能比父类方法少。这遵循了Liskov替换原则,即子类对象应当可以替换父类对象,而不改变程序的预期行为。具体地,这个规则体现在以下几个方面:


1. 受检异常(Checked Exception)

受检异常是指那些必须在方法签名中声明的异常,如 IOExceptionSQLException 等。这些异常被认为是可恢复的,需要被显式地捕获或声明。

在方法重写时,子类重写方法不能抛出比父类方法更多的受检异常。也就是说,子类方法声明的异常集合应该是父类方法异常集合的子集,即不能增加受检异常。

例如,父类方法抛出了 IOException,子类方法可以选择不抛出异常,或者抛出更具体的异常(如 FileNotFoundException),但不能抛出比父类更多的异常(如 SQLException)。

// 父类
class Parent {
    public void readFile() throws IOException {
        // 读取文件的代码
    }
}

// 子类重写
class Child extends Parent {
    @Override
    public void readFile() throws FileNotFoundException { // 只抛出更具体的异常(受检异常是允许的)
        // 读取文件的代码
    }
}

// 子类重写(错误示例)
// 如果子类抛出更多的受检异常,编译时会报错
class ChildError extends Parent {
    @Override
    public void readFile() throws SQLException { // 错误:不能抛出比父类更多的异常
        // 读取文件的代码
    }
}

2. 运行时异常(Unchecked Exception)

// 父类
class Parent {
    public void doSomething() {
        // 一些操作
    }
}

// 子类重写
class Child extends Parent {
    @Override
    public void doSomething() {
        // 可以抛出运行时异常,即使父类方法没有声明
        throw new NullPointerException("发生了空指针异常");
    }
}

3. 为什么有这些规则?

这些规则的设计是为了确保子类能够替代父类,且不会影响父类的原有行为。如果子类方法声明了更多的异常,调用者在使用子类时,可能会遇到比父类更多的异常,增加了调用者的处理复杂性。而运行时异常本身不要求强制捕获,因此可以在子类中引入新的运行时异常,不会影响到使用者的代码结构。


总结:

  • 受检异常(Checked Exception):子类方法可以抛出比父类方法更少的受检异常,但不能抛出更多的受检异常。
  • 运行时异常(Unchecked Exception):子类方法可以抛出新的运行时异常,不受限制。

这两个规则保证了程序的可维护性和一致性,遵循了 Liskov 替换原则:在运行时,你应该能够使用父类或子类对象,而不影响程序的正常行为。

有问题欢迎大佬来指出~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值