tags:

views:

344

answers:

7

I was recently quickly writing this little function 5 minutes ago when i got the compiler error unreachable statement

private static boolean isTransientField(String name, Class beanClass) {
        try {
            Field field = beanClass.getDeclaredField(name);
            return (field.getModifiers() & Modifier.TRANSIENT) == Modifier.TRANSIENT;
        } catch (Exception e) {return false;}

        return false;//unreachable statement
    }

Apparently my last return false is unreachable but why if my catch block only runs in exceptional cases?

+14  A: 

Because you have a return statement within the try.

Cellfish
+1. You beat me to it.
David Stratton
+1  A: 

Because you also have a return in your try block, so no matter what, a return is reached within the try catch construct.

David Stratton
+1  A: 

Because you've also got a return at the end of the try block.

aem
And an upvote to you as well.
David Stratton
+3  A: 

There are only two possible executions paths in your code.
1. The line

Field field = beanClass.getDeclaredField(name);

...works as expected and the next line returns:

return (field.getModifiers() & Modifier.TRANSIENT) == Modifier.TRANSIENT

2. An exception occurs and the return in the catch block executes.

Given those two paths, the third return statement cannot ever be reached.

Donal Boyle
There is actually a third possible execution path. A subclass of Throwable that isn't a sublcass of Exception (e.g. an Error) is thrown. It remains uncaught and bubbles up to the calling function, once again missing the third return statement.
ILMTitan
A: 

While all the above are true, the reasoning is that your code will either process and return successfully via the happy path, or it will throw an exception and be handled accordingly, so in essence, you've provided an if/else path of execution. The compiler will never reach the third return statement. If you removed the return false; from the catch block, the warning would go away. You would get the same warning if you were to handle your checked exception in some way (re-throw up the stack) because the code will either return as expected or throw and exception (another if/else path of execution).

Droo
+1  A: 

What you have is essentially the equivalent of the following:

if (something)
    return true;
else
    return false;
else
    return false;

Now, why would you have two else statements? That's right, you wouldn't.

Joe Philllips
A: 

Just to reiterate, don't use try/catch blocks for logical flow. The catch block should be used for handling exceptions/errors gracefully. Secondly, any function that is NOT declared void must return some form of the declared type, in your case a boolean value.

Possible solution

private static boolean isTransientField(String name, Class beanClass) 
{
    try 
    {
        Field field = beanClass.getDeclaredField(name);
        if((field.getModifiers() & Modifier.TRANSIENT) == Modifier.TRANSIENT)
        {
            return true;
        }
        else
        {
            return false;
        }

    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }
}
BrentAllenParrish
to compile, you will still need a return statement either within your `catch` or after the `try`/`catch`
akf
well the compiler would cough at this function
non sequitor
You are both right, should have left out the code sample. My point was that whether a exception occurs or not, the function must return a boolean value for the compiler to "not cough."
BrentAllenParrish