Typically, Java methods look like this:
public <U,V> U doSomething(V aReference) {
This usually means that the doSomething() method returns a null if it fails (for some reason) or a valid object reference. In some cases, a "valid object reference" may itself be null . For example, the aMap.get(k) method may return null if there is no k key or if there is a k key, but its corresponding value is null . Confusion!
Not to mention a NullPointerException if 50% of your LOC is not just a null check.
What's wrong with methods that look like this:
public <T> ReturnTuple<T> doSomething(V aReference) { T anotherObjRef = getValidObjT(); if (successful) { return ReturnTuple.getSuccessTuple(anotherObjRef); } else { return ReturnTuple.getFailureTuple("aReference can't be null"); } }
where the ReturnTuple<T> class is defined as follows:
class ReturnTuple<T> { private boolean success; // Read only if success == true private T returnValue; // Read only if success == false private String failureReason; // Private constructors, getters, setters & other convenience methods public static <T> ReturnTuple<T> getSuccessTuple(T retVal) { // This code is trivial } public static <T> ReturnTuple<T> getFailureTuple(String failureReason) { // This code is trivial } }
Then the calling code will look like this:
ReturnTuple<T> rt = doSomething(v); if (rt.isSuccess()) { // yay! } else { // boo hoo! }
So my question is: why is this scheme not more common? What is wrong with him?
Keep in mind that I am not asking for criticism of this exact code, but for criticizing this general idea.
Please note: the point here is not to get the code above for compilation, just to discuss the idea. Therefore, please do not be too pedantic regarding the correctness of the code :-).
Edit 1: Motivation
I think I should have added this section from the start, but better late than never ...
Have you ever wanted a method to be able to return two values โโat once? Or that returning a value can be de-tied from the ability to indicate success or failure?
It can also contribute to the idea of โโa method that is a neat and clean autonomous unit (low grip and high grip): handle all (or most) exceptions that occur during its execution (not to mention exceptions, for example, IllegalArgumentException ), quietly logarithm the causes of failures (rather than an ugly stack trace of an uncaught exception) and only bother the caller with the necessary information. IMHO it also promotes information hiding and encapsulation.
Make every effort to test, but when the code is deployed for the client, a fuzzy exception, an ugly stack trace, it all looks so unprofessional.
As above: you may have code that can generate 20 different exceptions, but you only catch 5-7 of them. As we all know, customers do the most damned things: rely on them to cause all other unverified 13-15 exceptions :-). You end up looking bad when you see a large stack trace (instead of the cause of the discrete error added to the logs).
This difference (for example) between showing the userโs stack trace in a web application and also showing a nicely formatted page with a 5xx error is something like: "An error has occurred and your request could not be completed. Admins were notified and corrected as soon as possible" etc.
This idea is not entirely irrelevant, since Java 8 provides an Optional class (as @JBNizet points out) and Google Guava also has an Optional class. This is a bit more.