【问题标题】:How to correctly exit from a method (having return type 'int') without actually returning any value at all in Java?如何正确退出方法(返回类型为'int')而不在Java中实际返回任何值?
【发布时间】:2020-09-24 12:25:26
【问题描述】:

以下是我在使用 LinkedList 实现堆栈时遇到的代码。编码可能看起来不正确且难以辨认。但是,问题不在主题范围内,并且 sn-p 仅提供上下文。

1.   public int pop() {
2.       int x;
3.       if (len==0){
4.           System.out.println("Already empty.");
5.           return;    //Says this method must return a result of type int?
6.       }
7.  
8.       int x = myLinkedList.deleteFromBegin();//this function returns the deleted integer
9.       --len;
10.      return x;
11.  }

上面的代码缺少从方法中退出的正式方式。第 5 行的 return 语句希望在特殊条件下不返回任何值。但通常该函数需要返回一个显示刚刚弹出的数字的 int。

【问题讨论】:

  • 您要么返回(带有值),要么抛出Throwable
  • 您也可以返回一个Optional<Integer>,但在这种情况下,一个例外似乎也是合适的(毕竟,Java's Stack 就是这样做的)。我建议返回一些“神奇”值,因为它们也可能都是列表中的元素。
  • @SudhirOjha 糟糕的主意。如何区分信号值和存储在列表中的实际0-1

标签: java return-value


【解决方案1】:

pop 似乎返回列表的头部,然后将其从列表中删除。那么如何处理空列表的情况完全取决于你想要的 API 类型。

快速失败

throw new RuntimeException("Empty list"); 

如果检测到无法弹出,因为列表为空,则抛出异常。这样,您可以为方法签名保留 int 类型。结果是,在调用 pop 之前,您希望确保列表不为空,并提供像 isEmpty() 或 len() 这样的函数,以便调用者可以在他身边进行检查。您基本上认为在空列表上调用 pop 是一个错误。

如果列表为空,则返回一个特殊值。

return -1;

这是危险的,应该避免。您的实现现在取决于该值未用于其他含义。例如,如果您使用 -1,但客户端代码希望合法地将数字 -1 添加到该列表中,则您无法将空列表与恰好为 -1 的标题元素区分开来。

包装类型以正确表示该概念。

return null;
// or
return Optional.empty();

要么使用整数的对象类型(Integer),要么使用“null”作为您的特殊值。或者使用 Optional 和该类型的捆绑方法 isPresent()。

请注意,调用者的工作量也很大。他必须检查 null 或 isPresent()。

结论

我个人更喜欢例外情况,因为弹出一个空列表没有意义,我希望它正确失败。它也很快失败,日志给了我失败的确切上下文。 null/可选或默认 int 值依赖于客户端执行正确的日志记录/异常处理,他们可能会忘记这样做。

【讨论】:

  • 这是对 -1 和 null 的一个很好的解释,谢谢。
【解决方案2】:

为此定义了一个例外:https://docs.oracle.com/javase/10/docs/api/java/util/EmptyStackException.html https://docs.oracle.com/javase/10/docs/api/java/util/Stack.html#pop() 使用。

这样你就可以在没有 int 的情况下“返回”。在所有其他情况下,您需要提供一个可能是堆栈内容的 int,这样您就不会知道它是空堆栈还是实际内容,除非您总是在弹出之前检查长度。

如果允许更改签名,则可以将返回类型更改为Optional<Integer>,其他情况返回Optional.empty()Optional.of(x)

【讨论】:

    【解决方案3】:

    如果你的返回类型是int,那么无论你在哪里写return - 你也应该返回一个有效的整数值。

    方法一:抛出异常:

    还有另一种选择退出方法而不返回 - 抛出异常JavaDoc

    3.       if (len==0){
    4.           System.out.println("Already empty.");
    5.           throw new Exception("Already empty");  // or new RuntimeException(). or any other exception.
    6.       }
    

    方法2:可选返回

    如果您想在返回 int 或什么都不返回时区分大小写,您可以将返回类型从 int 更改为 Optional<Integer> JavaDoc

    1.   public Optional<Integer> pop() {
    2.       int x;
    3.       if (len==0){
    4.           System.out.println("Already empty.");
    5.           return Optional.empty();    //Says this method must return a result of type int?
    6.       }
    7.  
    8.       int x = myLinkedList.deleteFromBegin();//this function returns the deleted integer
    9.       --len;
    10.      return Optional.of(x);
    11.  }
    

    在这种情况下,您需要在调用此方法的任何位置检查是否为空:

    Optional<Integer> x = pop();
    if (x.isPresent()){
        x.get() // process returned value.
    }
    

    【讨论】:

    猜你喜欢
    • 2018-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 2021-03-11
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多