Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Access a Method’s Result Value From the Finally Block

DZone's Guide to

How to Access a Method’s Result Value From the Finally Block

· Java Zone ·
Free Resource

How do you break a Monolith into Microservices at Scale? This ebook shows strategies and techniques for building scalable and resilient microservices.

While the JVM is a stack-based machine, the Java language doesn’t really offer you any way to access that Stack. Even if sometimes, in rare occasions, it would be very useful.

An example

Method result values are put on the stack. If you look at the following example:

public int method() {
    if (something)
        return 1;
 
    ...
    if (somethingElse)
        return 2;
 
    ...
    return 0;
}

If we ignore the halting problem, error handling, and other academic discussions, we can say that the above method will “certainly” return any value of 12, or 0. And that value is put on the stack prior to jumping out of the method.

Now, sometimes, it may be a use-case to take some action only when a given result value is returned. People might then be lured into starting the old flame-war discussion about whether multiple return statements are EVIL™and the whole method should have been phrased like this, instead:

public int method() {
    int result = 0;
 
    if (something)
        result = 1;
 
    ...
    if (somethingElse)
        result = 2;
 
    ...
    // Important action here prior to return
    if (result == 1337)
        log.info("hehehe ;-)");
 
    return result;
}

Of course, the above example is wrong, because, previously, the if (something) return 1 and if (something) return 2 statements immediately aborted method execution. In order to achieve the same with the “single-return-statement” technique, we’ll have to rewrite our code like this:


… and, of course, we can continue bike-shedding and flame-waring the use of curly braces and/or indentation levels, which shows we haven’t gained anything.

Accessing the return value from the stack

What we really wanted to do in our original implementation is a check just before returning to see what value is on the stack, i.e. what value will be returned. Here’s some pseudo-Java:

public int method() {
    int result = 0;
 
    if (something)
        result = 1;
    else {
 
        ...
        if (somethingElse)
            result = 2;
        else {
            ...
        }
    }
 
    // Important action here prior to return
    if (result == 1337)
        log.info("hehehe ;-)");
 
    return result;
}

The good news is: Yes we can! Here’s a simple trick that can be done to achieve the above:

public int method() {
    try {
        if (something)
            return 1;
 
        ...
        if (somethingElse)
            return 2;
 
        ...
        return 0;
    }
 
    // Important action here prior to return
    finally {
        if (reflectionMagic.methodResult == 1337)
            log.info("hehehe ;-)");
    }
}

The less good news is: You must never forget to explicitly assign the result. But every once in a while, this technique can be very useful to “access the method stack” when the Java language doesn’t really allow you to.

Of course…

Of course you could also just resort to this boring solution here:

public int method() {
    int result = actualMethod();
 
    if (result == 1337)
        log.info("hehehe ;-)");
 
    return result;
}
 
public int actualMethod() {
    if (something)
        return result = 1;
 
    ...
    if (somethingElse)
        return result = 2;
 
    ...
    return result = 0;
}

… and probably, most often, this technique is indeed better (because slightly more readable). But sometimes, you want to do more stuff than just logging in that finally block, or you want to access more than just the result value, and you don’t want to refactor the method.

Other approaches?

Now it’s your turn. What would be your preferred, alternative approach (with code examples?) E.g. using a Try monad? Or aspects?

How do you break a Monolith into Microservices at Scale? This ebook shows strategies and techniques for building scalable and resilient microservices.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}