当前位置: 首页 > 面试题库 >

抛出异常以控制流-代码有异味吗?

汪典
2023-03-14
问题内容

考虑以下代码(特别是Java):

public int doSomething()
{
    doA();

    try {
        doB();
    } catch (MyException e) {
        return ERROR;
    }

    doC();
    return SUCCESS;
}

其中doB()定义为:

private void doB() throws MyException

基本上,MyException仅在doB()满足某些条件(不是灾难性的,但确实需要以某种方式提高条件)的情况下存在,这样doSomething()才会知道会错误退出。

在这种情况下,您是否发现可以使用例外来控制流程?还是这是代码气味?如果是这样,您将如何重构呢?


问题答案:

这完全取决于错误条件是什么,以及方法的工作是什么。如果返回ERROR是为调用函数处理该错误的有效方法,那为什么会出错呢?

但是,通常这 一种气味。考虑一下:

bool isDouble(string someString) {
    try {
        double d = Convert.ParseInt32(someString);
    } catch(FormatException e) {
        return false;
    }
    return true;
}

这是一个很大的代码异味,因为您不希望出现双重值。您只想知道字符串是否包含双精度型。

有时,您使用的框架没有其他方式来完成您想要的事情。对于上述情况,有更好的方法:

bool isDouble(string someString) {
    bool success;
    Convert.TryParseInt32(someString, ref success);
    return success;
}

这类异常有一个特殊的名称,该名称是由我最近读过博客的人创造的,但可悲的是,我忘记了它的名字。如果您知道,请发表评论。最后但并非最不重要的一点是,上面是伪代码。我确定,我不是C#开发人员,因此上述内容无法编译,但是TryParseInt32/
ParseInt32我很好地证明了这一点,因此我将继续使用C#。

现在,到您的代码。让我们检查两个功能。一种闻起来,而另一种闻不到:

1.气味

public int setupSystem() {
    doA();

    try { doB(); }
    catch (MyException e)
    { return ERROR; }

    doC();
    return SUCCESS;
}

那是 代码的味道 ,因为当您要设置系统时,您不希望它失败。无法设置系统意味着您无法继续处理该错误。

2.好

public int pingWorkstation() {
    doA();

    try { doB(); }
    catch (MyException e)
    { return ERROR; }

    doC();
    return SUCCESS;
}

可以,因为该方法的目的是测试工作站是否仍然可以访问。如果不是,则这是该方法结果的一部分,而不是需要备用返回路径的特殊情况。



 类似资料:
  • 抛出异常的行为是否可能抛出不同的异常? 为了抛出异常,必须(可选地)分配新对象,并调用其构造函数(隐式调用fillinstacktrace)。在某些情况下,听起来像addSupressed也被称为。那么如果没有足够的内存会发生什么呢?JVM是否需要预分配内置异常?例如,(1/0)会抛出OutOfMemoryError而不是ArithmeticException吗? 此外,构造函数是一个方法调用,因

  • 我正在使用RabbitMQ的spring cloud stream。我试图通过在运行时删除队列并将消息发送到删除的队列来进行否定测试。 我正在侦听来自队列1的消息,并将消息发送到队列2(已删除的一个)。我原以为上面的代码会抛出异常,但事实并非如此。甚至从队列1读取的消息也已被确认。我在队列1和队列2上有一个死信队列,但消息没有进入DLQ。

  • 问题内容: 最近,我的一位同事编写了一些代码,以捕获整个方法周围的空指针异常,并返回单个结果。我指出了空指针可能有多种原因,因此我们将其更改为对一个结果的防御性检查。 但是,捕获NullPointerException对我来说似乎是错误的。在我看来,空指针异常是错误代码的结果,而不是系统中预期的异常。 在任何情况下捕获空指针异常都有意义吗? 问题答案: 是的,捕获任何东西几乎总是一种代码气味。该C

  • 在你可以捕获异常之前,一些代码必须抛出一个异常。任何代码都可能会抛出异常:您的代码,来自其他人编写的包(例如Java平台附带的包)或Java运行时环境的代码。无论是什么引发的异常,它总是通过 throw 语句抛出。 您可能已经注意到,Java平台提供了许多异常类。所有类都是Throwable类的后代,并且都允许程序区分在程序执行期间可能发生的各种类型的异常。 您还可以创建自己的异常类来表示在您编写

  • 问题内容: 考虑以下代码: 无需添加方法签名即可编译该代码。(它与同样表现到位,太)。 我理解为什么 可以 安全地运行它,因为实际上不能将其引发在块中,因此不能引发已检查的异常。我有兴趣知道在何处指定此行为。 并非永远都不会达到目标:以下代码也会编译: 但是,如果抛出一个检查的异常,它不会像我期望的那样编译: 在JLS Sec 11.2.2中 ,它说: 一,其抛出的表达式语句(§14.18)具有静

  • 问题内容: 我试图在Netbeans中重构一个大型程序,但我有点迷茫。我从来没有非常模块化,但是现在通过实际学习如何做到这一点来尝试纠正这种情况,并在将来纠正这种情况。不幸的是,我在将某些教程翻译成我的程序时遇到了麻烦。所以我希望这里有人可以帮忙。目前,我正在尝试分解一部分采用特定格式的文件并制成表格的代码。我知道我需要创建一个类并使用它来创建表对象,但是我不确定如何做。我有一个主文件,用于获取文