简体   繁体   English

在 Java 中,如何正确退出方法(返回类型为“int”)而不实际返回任何值?

[英]How to correctly exit from a method (having return type 'int') without actually returning any value at all in Java?

Below is a code I encountered when implementing a Stack using LinkedList.下面是我在使用 LinkedList 实现 Stack 时遇到的代码。 The coding might seem incorrect and illegible.编码可能看起来不正确且难以辨认。 However, the question is outside the topic and the snippet only supplies a context.但是,问题不在主题范围内,并且该代码段仅提供了上下文。

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.  }

The above code is lacking a formal way of exiting from a method.上面的代码缺乏从方法中退出的正式方式。 The return statement at line 5 wants to return no value under a special condition.第 5 行的 return 语句希望在特殊条件下不返回任何值。 But normally the function needs to return an int showing the number just popped out.但通常该函数需要返回一个 int 来显示刚刚弹出的数字。

pop seems to return the head of your list and then remove it from the list. pop 似乎返回列表的头部,然后将其从列表中删除。 Then how to handle the case of an empty list fully depend of the type of API you want.那么如何处理空列表的情况完全取决于您想要的 API 类型。

Fail fast快速失败

throw new RuntimeException("Empty list"); 

If you detect you cannot pop, because the list is empty, you throw an exception.如果检测到无法弹出,因为列表为空,则抛出异常。 This way you can keep int type for your method signature.这样你就可以为你的方法签名保留 int 类型。 The consequence is that before calling pop, you'd expect on to be sure the list is not empty and like provide a function like isEmpty() or len() so that the caller can check on his side.结果是,在调用 pop 之前,您希望确保列表不为空,并提供像 isEmpty() 或 len() 这样的函数,以便调用者可以检查他的一面。 You basically consider calling pop on an empty list to be an error.您基本上认为在空列表上调用 pop 是一个错误。

Return a special value if the list is empty.如果列表为空,则返回一个特殊值。

return -1;

This is dangerous and to be avoided.这是危险的,需要避免。 Your implementation is now depending of that value not being used for other meaning.您的实现现在取决于该值不被用于其他含义。 if you use -1 for example but the client code want to legitimately add the number -1 to that list, you can't differentiate an empty list from a header element that happen to be -1.例如,如果您使用 -1,但客户端代码想要将数字 -1 合法地添加到该列表中,则您无法将空列表与碰巧为 -1 的标题元素区分开来。

Wrap the type to correctly represent that concept.包装类型以正确表示该概念。

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

Either use the object type for integers (Integer) and use "null" as your special value.要么使用整数(Integer)的对象类型并使用“null”作为您的特殊值。 Or use Optional and the bundled method isPresent() of that type.或者使用 Optional 和该类型的捆绑方法 isPresent() 。

Please notice that the effort is as high on the caller.请注意,呼叫者的努力程度很高。 He has to check for null or isPresent().他必须检查 null 或 isPresent()。

Conclusion结论

Personally I prefer the exception case, as it doesn't make sense to pop an empty list and I want that to fail properly.我个人更喜欢例外情况,因为弹出一个空列表没有意义,我希望它正确失败。 It also fail fast and a log give me the exact context where it failed.它也会快速失败,并且日志为我提供了失败的确切上下文。 A null/optional or default int value relies on the client performing the proper logging/exception handling and they may forget to do it.空/可选或默认 int 值依赖于客户端执行正确的日志记录/异常处理,他们可能会忘记这样做。

There is a defined Exception for this: https://docs.oracle.com/javase/10/docs/api/java/util/EmptyStackException.html that https://docs.oracle.com/javase/10/docs/api/java/util/Stack.html#pop() uses.有一个定义的异常: 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()使用。

That way you can "return" without an int.这样你就可以在没有 int 的情况下“返回”。 In all other cases you need to supply an int which might be contents of the stack so you won't know if it is an empty stack or actual content unless you always check length before popping.在所有其他情况下,您需要提供一个 int ,它可能是堆栈的内容,因此除非您总是在弹出之前检查长度,否则您将不知道它是空堆栈还是实际内容。

If you are allowed to change the signature, you can change return type to Optional<Integer> and return Optional.empty() and Optional.of(x) for the other cases.如果允许更改签名,则可以将返回类型更改为Optional<Integer>并返回Optional.empty()Optional.of(x)以用于其他情况。

If your return type is int then wherever you write return - you also should return a valid integer value.如果你的返回类型是int那么无论你在哪里写return - 你也应该返回一个有效的整数值。

Approach 1: Throw an exception:方法一:抛出异常:

There is another option to exit the method without returning - to throw an exception JavaDoc :还有另一个选项可以退出方法而不返回 - 抛出异常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.       }

Approach 2: Return Optional方法二:返回可选

If you want to segregate case when you return int or nothing, you could change return type from int to Optional<Integer> JavaDoc如果您想在返回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.  }

in this case you will need to check for empty wherever this method is called:在这种情况下,您需要在调用此方法的任何地方检查是否为空:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM