MST

星途 面试题库

面试题:Java多态重写方法异常处理的实际应用考察

假设有一个Java的图形绘制框架,有一个抽象类Shape,其中有一个抽象方法draw,声明抛出IOException。现在有子类Circle和Rectangle继承自Shape并重写draw方法。在实际应用场景中,Circle可能因为资源不足抛出OutOfMemoryError,Rectangle可能因为坐标计算错误抛出IllegalArgumentException,这样的异常处理在多态重写规则下是否合理?如果不合理该如何调整?请详细阐述。
46.8万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 分析合理性
    • 在多态重写规则下,这种异常处理不完全合理。重写方法不能抛出比被重写方法更宽泛的异常。抽象类Shapedraw方法声明抛出IOException,而Circle类的draw方法抛出OutOfMemoryError(这是一个错误Error,不属于Exception体系,但它是运行时异常的超类),Rectangle类的draw方法抛出IllegalArgumentException(运行时异常)。虽然运行时异常不需要显式声明抛出,但从方法重写的语义一致性角度看,这种抛出不同类型异常的情况会破坏多态调用时对异常处理的预期。
  2. 调整方式
    • 方式一:修改抽象类方法声明
      • 可以在Shape类的draw方法中声明抛出RuntimeException,这样子类抛出OutOfMemoryErrorIllegalArgumentException(都属于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方法中捕获特定异常,然后重新抛出与Shapedraw方法声明相符的异常(比如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);
              }
          }
      }
      

通过以上两种方式,可以使异常处理在多态重写规则下更加合理。