【问题标题】:Faking abstract methods using exceptions in Java在 Java 中使用异常伪造抽象方法
【发布时间】:2014-02-27 18:26:22
【问题描述】:

我被问到这个问题,坦率地说我很难过:

我们可以尝试用异常来伪造它们,而不是编写抽象方法,如下所示:

public int someMethod(int someparameter) {
    throws new RuntimeException("unimplemented");
}

这样做的目的是什么?谁能提供一个上面试图伪造的抽象方法的代码示例?任何帮助是极大的赞赏。谢谢。

【问题讨论】:

  • 多么糟糕的主意。编译器永远无法提醒您忘记实现一个。没有什么能阻止你使用如果你调用它们就会爆炸的方法来实例化一个类。
  • 嗯,这就是我的想法。问题如下(这是一个古老的测试问题我错了,我仍然不明白。无论如何,问题如下:“解释假货以何种方式与摘要具有相似的目的方法,还要说明它不服务的目的。”
  • 测试题是 Java 特有的吗?我可以看到,如果问题是这样的,这个答案可能是有意义的,如果你必须用一种没有抽象方法的语言编写,你怎么能伪造这个。 (虽然我不知道有异常但没有抽象方法的语言。)
  • 是的,这是一个 Java 测试。

标签: java exception abstract-methods


【解决方案1】:

我可以想到一个(可能)有效的用例:您有一个抽象类,并且整个项目中还有许多其他类对其进行了扩展。 (或者抽象类在一个开源库中,所以你不知道整个宇宙中还有哪些其他类可以从它扩展而来。)现在,你发现向这个类添加新的抽象方法很有用。但是,如果您将abstract 方法添加到该类,这会破坏已经扩展它的所有其他类,因为需要更改这些类以包含新方法的覆盖。所以我可以看到,在某些情况下,将它们添加为非抽象方法并让它们抛出异常以防万一扩展它的 new 类使用新方法但忘记编写重写方法。它不会在编译时被捕获,但至少它可能在测试期间被捕获。

我不确定这个原因有多合理,因为也可以定义一个新的抽象类NewImprovedWhatever 来扩展旧的抽象类,以包含新方法。不过,这可能会带来其自身的维护挑战。我不确定。

我确实注意到Java定义了一个抽象类java.net.SocketImpl,其中包含两个非抽象方法shutdownInput()shutdownOutput(),其默认实现是抛出异常:

protected void shutdownInput() throws IOException {
  throw new IOException("Method not implemented!");
}

cmets 表明它们是在 1.3 中添加的,所以也许这就是它这样做的确切原因,即不需要修改已经扩展 SocketImpl 的其他类。但我不确定。

无论如何,如果类是从头开始设计的,那么这样的设计肯定是非常糟糕的代码。但是,当必须修改现有代码时,我们在课堂上学到的好的 O-O 概念在实践中并不总是那么好。

【讨论】:

    【解决方案2】:

    我有时会从功能尚未实现的方法中抛出UnsupportedOperationException。 (还有一个NotImplementedException in Apache Commons,它是UnsupportedOperationException 的子类。)这始终意味着作为一个占位符,并向使用相关类或服务的其他人发送该方法尚未完成的消息。然而,这样的代码从未投入生产。

    【讨论】:

      【解决方案3】:

      这样做的目的是有目的地编写BAD CODE
      如果想迷惑读者,想让他们感受到阅读代码的痛苦,那么就写这样的代码。
      这也表明代码缺乏设计技巧。
      写得不好的 API 会有这样的代码。
      不要那样做。

      【讨论】:

      • 这可能是非常糟糕的代码,但标准 Java API 有时会提供这样的行为。例如,请参阅 Collections API 常见问题解答中的“UnsupportedOperationException”:docs.oracle.com/javase/1.5.0/docs/guide/collections/…
      • 即使iterators remove() 方法会抛出这个UnsupportedOperationException,并且Collections API 中的大多数数据结构都不支持迭代器的remove() 方法。因此,在他们的 iterator 上调用 remove() 将引发此类异常。
      猜你喜欢
      • 1970-01-01
      • 2019-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-13
      • 2015-01-06
      • 2013-09-19
      • 1970-01-01
      相关资源
      最近更新 更多