Home > OS >  How to return a value from try, catch, and finally by using condition?
How to return a value from try, catch, and finally by using condition?

Time:05-18

My get()method have a red line, it tells me

this method must return a result of type char

public char get() {
    mutex.lock();
    char c = buffer[out];
    try {
        while (count == 0) {  
            okConsume.await();
        }
        out = (out   1) % buffer.length;
        count--;
        System.out.println("Consuming "   c   " ...");
        okConsume.signalAll();
        return c;
    }catch(InterruptedException ie) {
        ie.printStackTrace();
    }finally {
        mutex.unlock();
    }
    
}

CodePudding user response:

Not sure what 'by using condition' is about. The problem, however, is clear from your snippet.

Your exception handling sucks.

It's allright. For some bizarre reason most examples and as far as I know every major IDE messes this up, so it's not your fault. The problem is, ie.printStrackTrace() is horrible and should never be written like this. That is not how you handle exceptions - even exceptions that you don't want to think about.

The specific problem here is what that really means: This:

} catch (Something e) {
  e.printStackTrace();
}

means, quite literally: Whenever problem X occurs, print half of the information about X (notably using a method name that is a lie - printStackTrace does not print the stack trace, it prints way more than that. It's bad form to use misnamed methods), toss the other half in the garbage, and just keep going.

And that is the problem here: If an exception occurs, print half of the information about the problem and keep going. Go on to.. what? The end of the method - and thus, the compiler correctly complains: It doesn't know what to return, and you told it to 'keep going'.

The fix is simple enough. Pick one of these:

  1. Preferred solution: Handle your exceptions properly. It's not as hard as you might think.
  2. The 'eh whatever I do not want to think about it' solution needs to always be: throw new RuntimeException("uncaught", e); instead of e.printStackTrace(). Fix your IDE's templates!

In this specific case, 'fix it properly' is quite easy. InterruptedException cannot possible occur unless you explicitly write some code that invokes the interrupt() method of your thread object. It is rather unlikely that you do so, but if you do, you have a specific reason for it. Whatever that might be - program that. The point of the interrupt is to interrupt the await method out, to 'short circuit it'. What do you want to happen then? Perhaps that this method exits via an exception, in which case, throw new Whatever() would do the job, pick a proper exception type and document it in your method. Possibly even just add throws InterruptedException to your method. Answering 'how to do exceptions in java' is a bit broad for a stack overflow question, but there are many tutorials.

Most likely you don't have any .interrupt() calls anywhere in your code in which case the catch block is irrelevant, it will never occur. throw new RuntimeException("uncaught", e); is precisely correct - it is simple, it does not delete any information, it does not cause compiler issues such as the one that led you to asking this question, and it clearly communicates to the reader of the code what is happening (namely: That you do not expect this exception to occur or haven't bothered to write anything specific about it if it does, and you want to remove the bother of dealing with it from any callers).

CodePudding user response:

Your code should cover all the possible scenario. Now it doesn't because you're not returning from the method if exception occur.

The return statement placed inside the try will be unreachable in case of exception.

For more information on Exception-handling, I suggest to have a look at this tutorial.

There are two ways to fix it:

  • place return statements in both try and catch blocks;
    public char get() {
        mutex.lock();
        char c = buffer[out];
        try {
            // some code
            return c;
        } catch (InterruptedException ie) {
            ie.printStackTrace();
            return c;
        } finally {
            mutex.unlock();
        }
    }
  • place the return statement after the finally block;
    public char get() {
        mutex.lock();
        char c = buffer[out];
        try {
            // some code
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        } finally {
            mutex.unlock();
        }
        return c;
    }
  • Related