一.抛出处理:


二.实操:
1.throw:

结果:

2.throws:

结果:

三.优化:


结果:

四.补充:java中父类没有抛出异常,子类就不能抛出异常
在Java异常处理机制中,子类方法抛出的异常类型确实受到父类方法的严格约束,这个设计背后蕴含着深刻的面向对象思想和工程考量。让我们像剥洋葱一样层层解析这个机制的精妙之处:
1.里氏替换原则的守护者 当子类重写父类方法时,任何调用父类方法的代码都应该能无缝替换成子类对象。想象一下,如果父类方法声明"我永不抛出异常",而子类突然抛出个IOException,就像承诺"绝对安全"的电器突然漏电——这会彻底破坏代码的可预测性。
2.编译器的温柔防线 Java编译器在编译阶段就会严格检查,子类重写方法时:
- 只能抛出父类方法声明中的异常(包括其子类异常)
- 或者根本不抛出检查型异常(unchecked exception如RuntimeException不受限) 就像贴心的安全检查员,提前避免运行时可能出现的意外崩溃。
3.三种典型场景的生动比喻:
// 场景1:父类不抛异常 - 子类必须保持"纯洁"
class Parent {
void foo() { /* 安全操作 */ }
}
class Child extends Parent {
@Override
void foo() throws IOException { /* 违规! */ } // 编译报错
}
// 场景2:父类声明异常 - 子类可以"更精确"
class Parent {
void bar() throws Exception { /* 可能出错 */ }
}
class Child extends Parent {
@Override
void bar() throws IOException { /* 允许! */ } // IOException是Exception子类
}
// 场景3:运行时异常 - 自由的"野孩子"
class Parent {
void baz() { /* 看似安全 */ }
}
class Child extends Parent {
@Override
void baz() throws NullPointerException { /* 允许! */ } // 非检查型异常
}
4.架构师的智慧选择 这种限制实际上鼓励我们:
- 使用更精细的异常层次设计
- 优先用组合替代继承处理异常场景
- 对不可恢复错误使用unchecked exception 就像老练的厨师,既保证菜品安全又不失灵活性。
5.绕过限制的优雅之道 当确实需要扩展异常时,可以:
// 方法1:用包装模式转化异常
@Override
void foo() {
try {
doSomethingDangerous();
} catch (IOException e) {
throw new RuntimeException("包裹检查异常", e);
}
}
// 方法2:模板方法模式
abstract class Parent {
final void template() { // final阻止重写
// ...公共逻辑
doProcess();
// ...公共逻辑
}
abstract void doProcess(); // 子类实现细节
}
这个机制就像Java语言中的交通规则,看似限制自由,实则是为了避免更大的系统混乱。理解它,就能写出既安全又灵活的优雅代码。
2325

被折叠的 条评论
为什么被折叠?



