Methods should always try be designed to return a value that allows the developer to learn about the current state of the object and/or the result of an operation. This advice is consistent with guideline EXP00-J. Do not ignore values returned by methods. The returned value should be as representative as possible of the last known state and should be chosen with keeping in mind the perceptions and mental model of the developer in mind.
Feedback can also be provided by throwing either standard or custom exception objects derived from the Exception
class. With this approach, the developer can still get precise information about the outcome of the method and proceed to take the necessary actions. To do so, the exception should provide a detailed account of the abnormal condition at the appropriate abstraction level.
APIs should use a combination of these approaches both to help clients distinguish correct results from incorrect results ones and to encourage careful handling of any incorrect results. At the same time, in In some cases, an error value instead of an exception should be returned, and vice versa. A method should not return a value that could can hold both indicate valid return data or and an error indicatorcode; see ERR52-JG. Avoid in-band error indicators for more details.
...
As shown in this noncompliant code example, a the updateNode()
method modifies a node if it can find it in a linked list and does nothing if the node is not in the list. But this method fails to indicate whether it modified any node. A method can silently corrupt the state of the object if it provides little communication describing what it did.
Code Block | ||
---|---|---|
| ||
public void updateNode(int id, int newValue) { Node current = root; while (current != null) { if (current.getId() == id) { current.setValue(newValue); break; } current = current.next; } } |
This method fails to indicate whether it modified any node. A method can silently corrupt the state of the object if it provides little feedback about the actions it performed.
Compliant Solution (boolean
)
This compliant solution returns the result of the operation : as true
if it modified a node and false
otherwise: if it did not.
Code Block | ||
---|---|---|
| ||
public boolean updateNode(int id, int newValue) { Node current = root; while (current != null) { if (current.getId() == id) { current.setValue(newValue); return true; // Node successfully updated } current = current.next; } return false; } |
Compliant Solution (exception)
This compliant solution returns the modified Node
when one is found and throws a NodeNotFoundException
when the node is not available in the list.Using exceptions to indicate failure can be a good design choice, but throwing exceptions is not always appropriate. In general, a method should throw an exception only when it is always expected to succeed—an exception is appropriate here only if the developer believes the method will always succeed.
Code Block | ||
---|---|---|
| ||
public Node updateNode(int id, int newValue) throws NodeNotFoundException { Node current = root; while (current != null) { if (current.getId() == id) { current.setValue(newValue); return current; } current = current.next; } throw new NodeNotFoundException(); } |
Using exceptions to indicate failure can be a good design choice, but throwing exceptions is not always appropriate. In general, a method should throw an exception when it is expected to succeed but an unrecoverable situation occurs or when it expects a method higher up in the call hierarchy to initiate recovery.
Compliant Solution (null
return value)
This compliant solution returns the updated Node
so that the developer can simply check for a null
value if the operation fails. Return values for methods can vary depending on the control flow or the information that the developer finds more useful.
Code Block | ||
---|---|---|
| ||
public Node updateNode(int id, int newValue) { Node current = root; while (current != null) { if (current.getId() == id) { current.setValue(newValue); return current; } current = current.next; } return null; } |
Return values for methods can vary depending on the control flow or the information that the developer finds more useful.
A A return value that might be null is an in-band error indicator, which is discussed more thoroughly in 52. ERR52-JG. Avoid in-band error indicators. This design is permitted but is considered inferior to other designs, such as those shown in the other compliant solutions in this guideline.
...