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

huangapple go评论61阅读模式
英文:

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

问题

1.   public int pop() {
2.      int x;
3.      if (len==0){
4.          System.out.println("Already empty.");
5.          return -1;  // 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. }
英文:

Below is a code I encountered when implementing a Stack using LinkedList. 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. But normally the function needs to return an int showing the number just popped out.

答案1

得分: 4

pop操作似乎会返回列表的头部元素,然后从列表中移除该元素。那么如何处理空列表的情况完全取决于所需的API类型。

快速失败

throw new RuntimeException("空列表");

如果检测到无法进行pop操作,因为空列表,就抛出异常。这种方式可以保持方法签名的整数类型。其结果是,在调用pop之前,您应该确保列表不为空,并且可以提供像isEmpty()或length()这样的函数,以便调用者可以在其端检查。基本上,认为在空列表上调用pop是一个错误。

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

return -1;

这是危险的,应该避免使用。现在,您的实现依赖于该值不被用于其他含义。例如,如果您使用-1,但客户端代码想要合法地将数字-1添加到该列表中,您无法区分空列表和偶然为-1的头元素。

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

return null;
// 或者
return Optional.empty();

要么使用整数的对象类型(Integer),并将"null"作为您的特殊值。要么使用Optional<Integer>,并使用该类型的bundled方法isPresent()。

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

结论

就个人而言,我更喜欢异常情况,因为对空列表执行pop操作是没有意义的,我希望它能适当地失败。它还能够快速失败,并且日志会向我提供出错的确切上下文。与空/可选或默认整数值不同,依赖于客户端执行适当的日志记录/异常处理,他们可能会忘记执行这些操作。

英文:

pop seems to return the head of your list and then remove it from the list. Then how to handle the case of an empty list fully depend of the type of API you want.

Fail fast

throw new RuntimeException(&quot;Empty list&quot;); 

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. The consequence is that before calling pop, you'd expect one to be sure the list is not empty and can provide a function like isEmpty() or length() so that the caller can check on his side. You basically consider calling pop on an empty list to be an error.

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.

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. Or use Optional<Integer> and the bundled method isPresent() of that type.

Please notice that the effort is as high on the caller. He has to check for null or 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.

答案2

得分: 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()使用了该异常。

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

如果允许更改签名,您可以将返回类型更改为Optional<Integer>,并分别返回Optional.empty()Optional.of(x)用于其他情况。

英文:

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.

That way you can "return" without an 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.

If you are allowed to change the signature, you can change return type to Optional&lt;Integer&gt; and return Optional.empty() and Optional.of(x) for the other cases.

答案3

得分: 1

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

方法1: 抛出异常:

还有另一种选项可以在不返回的情况下退出方法 - 抛出异常 Java文档:

3.       if (len==0){
4.           System.out.println("已经为空。");
5.           throw new Exception("已经为空");  // 或者 new RuntimeException(),或其他任何异常。
6.       }

方法2: 返回 Optional

如果您想区分返回 int 或什么都不返回的情况,您可以将返回类型从 int 更改为 Optional<Integer> Java文档

1.   public Optional<Integer> pop() {
2.       int x;
3.       if (len==0){
4.           System.out.println("已经为空。");
5.           return Optional.empty();    // 说此方法必须返回 int 类型的结果?
6.       }
7.
8.       int x = myLinkedList.deleteFromBegin();  // 此函数返回已删除的整数
9.       --len;
10.      return Optional.of(x);
11.  }

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

Optional<Integer> x = pop();
if (x.isPresent()){
    x.get(); // 处理返回的值。
}
英文:

If your return type is int then wherever you write return - you also should return a valid integer value.

Approach 1: Throw an exception:

There is another option to exit the method without returning - to throw an exception JavaDoc:

3.       if (len==0){
4.           System.out.println(&quot;Already empty.&quot;);
5.           throw new Exception(&quot;Already empty&quot;);  // 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&lt;Integer&gt; JavaDoc

1.   public Optional&lt;Integer&gt; pop() {
2.       int x;
3.       if (len==0){
4.           System.out.println(&quot;Already empty.&quot;);
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&lt;Integer&gt; x = pop();
if (x.isPresent()){
    x.get() // process returned value.
}

huangapple
  • 本文由 发表于 2020年9月24日 20:25:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/64046416.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定