面试题答案
一键面试- 分析合理性:
- 在多态重写规则下,这种异常处理不完全合理。重写方法不能抛出比被重写方法更宽泛的异常。抽象类
Shape
的draw
方法声明抛出IOException
,而Circle
类的draw
方法抛出OutOfMemoryError
(这是一个错误Error
,不属于Exception
体系,但它是运行时异常的超类),Rectangle
类的draw
方法抛出IllegalArgumentException
(运行时异常)。虽然运行时异常不需要显式声明抛出,但从方法重写的语义一致性角度看,这种抛出不同类型异常的情况会破坏多态调用时对异常处理的预期。
- 在多态重写规则下,这种异常处理不完全合理。重写方法不能抛出比被重写方法更宽泛的异常。抽象类
- 调整方式:
- 方式一:修改抽象类方法声明:
- 可以在
Shape
类的draw
方法中声明抛出RuntimeException
,这样子类抛出OutOfMemoryError
和IllegalArgumentException
(都属于RuntimeException
体系)就符合重写规则。
public abstract class Shape { public abstract void draw() throws RuntimeException; }
public class Circle extends Shape { @Override public void draw() throws RuntimeException { // 模拟资源不足抛出OutOfMemoryError if (true) { throw new OutOfMemoryError(); } } }
public class Rectangle extends Shape { @Override public void draw() throws RuntimeException { // 模拟坐标计算错误抛出IllegalArgumentException if (true) { throw new IllegalArgumentException(); } } }
- 可以在
- 方式二:捕获并重新抛出合适的异常:
- 在子类的
draw
方法中捕获特定异常,然后重新抛出与Shape
类draw
方法声明相符的异常(比如IOException
,根据实际需求选择合适的异常类型)。
public class Circle extends Shape { @Override public void draw() throws IOException { try { // 图形绘制相关代码 if (true) { throw new OutOfMemoryError(); } } catch (OutOfMemoryError e) { throw new IOException("图形绘制时资源不足", e); } } }
public class Rectangle extends Shape { @Override public void draw() throws IOException { try { // 图形绘制相关代码 if (true) { throw new IllegalArgumentException(); } } catch (IllegalArgumentException e) { throw new IOException("图形坐标计算错误", e); } } }
- 在子类的
- 方式一:修改抽象类方法声明:
通过以上两种方式,可以使异常处理在多态重写规则下更加合理。