首页 > 解决方案 > 让编译器知道 Java 函数永远不会返回

问题描述

我的 Scala 代码(实现 Jackson 反序列化器)调用了一个 Java 函数,该函数总是抛出 ( DeserializationContext.handleUnexpectedToken)。如果这将是一个 Scala 函数,它的返回类型将是Nothing,并且编译器会在它无法访问之后知道代码。目前我???在函数调用之后使用来标记它,我也可以使用 anythrow代替,但也许有更好的方法,一些注释或什么?

  class XDeserializer extends StdDeserializer[X](classOf[X]) {
    def deserialize(p: JsonParser, ctxt: DeserializationContext) = {
      if (p.getCurrentToken.equals(JsonToken.VALUE_STRING)) {
        /* .... */
      } else {
        ctxt.handleUnexpectedToken(classOf[X], p)
        ??? // is there a better way?
      }
    }
  }

标签: scalaexception

解决方案


EDIT2:TLDR 没关系,也许只是将该函数包装在一个返回 Nothing 的函数中?

我通常通过将异常声明为结果类型来做到这一点。让我用 Java 向你展示。应该很容易翻译。

RuntimeException functionThatAlwaysThrows() {
    throw new WhateverRuntimeException();
}

然后我只是通过在 throw 前面加上前缀来使用它:

throw functionThatAlwaysThrows();

请注意,这里使用的“抛出”实际上从未“发生”,它只是告诉编译器发生了什么。由于异常是在函数内部抛出的,因此如果忘记添加“抛出”,结果不会发生变化。

通常,如果您忘记了,编译器的流程分析会通知您;当然不是完全命令式的代码,但你的问题似乎是在谈论一个无法省略它的上下文。

有一个设计决定来决定将哪种类型的异常声明为返回类型;实际上,它不一定与抛出的异常有关,但如果是的话,它可能就不那么令人困惑了。当然,适用于已检查和未检查的异常,但我猜 Scala 没有已检查的异常。

编辑:我现在看到你不是被调用函数的实现者。所以我想这个想法是简单地将该函数包装在一个函数中,正如我所描述的那样。或者它可能已经将异常声明为返回类型?


推荐阅读