aspose file tools*
The moose likes Beginning Java and the fly likes Throwing a RuntimeException Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Throwing a RuntimeException" Watch "Throwing a RuntimeException" New topic
Author

Throwing a RuntimeException

Paul Mrozik
Ranch Hand

Joined: Feb 10, 2013
Posts: 117

I'm having difficulty finishing all the problems in the Error Handling and Exceptions chapter of TIJ. Here's no. 11:

Show that OnOffSwitch.java can fail by throwing a RuntimeException inside the try block.


And the code:



The compiler rudely bawls at me with this:

OnOffSwitch.java:22: unreachable statement
f();


My understanding is that the RuntimeException makes it unreachable, and the compiler is smart enough to recognize that since it moves to a higher context. I am using an outdated version of the book, so perhaps it did compile a few versions back. Eckel was attempting to demonstrate the use of finally, which I hope I understand. No matter what kind of Exception is thrown, finally will execute and bring back an object to its intended state.

Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

As long as I can remember, that unreachable code error would have occurred. It might be an error in the book, or it might be that the behavior was indeed difference several versions ago.

If you want to make the code do what it was intended to you can do this:



The compiler could fail with the same unreachable code error, since it can tell that the if condition is always true, but it allows if (true) and if (false), presumably specifically for testing and debugging purposes.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Paul Mrozik wrote: Eckel was attempting to demonstrate the use of finally, which I hope I understand. No matter what kind of Exception is thrown, finally will execute and bring back an object to its intended state.



Correct.

When you have a finally block, then no matter how the try and catch portions complete--return, throw, break, continue, or normal completion--finally will be executed. That includes returning, throwing, etc. out of the catch blocks, not just the try.
Paul Mrozik
Ranch Hand

Joined: Feb 10, 2013
Posts: 117



The compiler could fail with the same unreachable code error, since it can tell that the if condition is always true, but it allows if (true) and if (false), presumably specifically for testing and debugging purposes.

I honestly haven't the faintest idea why that worked, but it did. Thanks.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Paul Mrozik wrote:I honestly haven't the faintest idea why that worked, but it did. Thanks.


Like I said, the designers decided to make an explicit exception to the "unreachable code" rule for this particular case, to facilitate testing and debugging. At least I assume that's why.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3014
    
  10
Jeff Verdegan wrote:The compiler could fail with the same unreachable code error, since it can tell that the if condition is always true, but it allows if (true) and if (false), presumably specifically for testing and debugging purposes.

No, the compiler is not allowed to fail in this case. It's obeying the JLS, which specifically requires that an if statement be treated this way. Here's the explanation:
As an example, the following statement results in a compile-time error:

because the statement x=3; is not reachable; but the superficially similar case:

does not result in a compile-time error. An optimizing compiler may realize that the statement x=3; will never be executed and may choose to omit the code for that statement from the generated class file, but the statement x=3; is not regarded as "unreachable" in the technical sense specified here.

The rationale for this differing treatment is to allow programmers to define "flag variables" such as:

and then write code such as:

The idea is that it should be possible to change the value of DEBUG from false to true or from true to false and then compile the code correctly with no other changes to the program text.

In reality, no one uses DEBUG like this anymore; they use proper logging frameworks (which will work better once we get lamdas). But back in the mid-nineties, such code was not too uncommon among the C/C++ programmers that Java was targeting for its audience.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Mike Simmons wrote:
Jeff Verdegan wrote:The compiler could fail with the same unreachable code error, since it can tell that the if condition is always true, but it allows if (true) and if (false), presumably specifically for testing and debugging purposes.

No, the compiler is not allowed to fail in this case. It's obeying the JLS, which specifically requires that an if statement be treated this way. Here's the explanation:


Yes, I know. And my explanation as to why jives with that in what you quoted from the JLS.

When I said the compiler could fail, I meant that there was no technical reason that it couldn't. I take it as a given that whatever the compiler does, it does so because the JLS says it has to (or is silent on the issue). I guess I could have been a little more explicit.

In reality, no one uses DEBUG like this anymore


I use it all the time, although I go directly for if (true) or if (false).
Paul Mrozik
Ranch Hand

Joined: Feb 10, 2013
Posts: 117

Thank you both, Jeff and Mike. That cleared things up a bit.

Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

You're welcome!
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Jeff Verdegan wrote:
Paul Mrozik wrote: Eckel was attempting to demonstrate the use of finally, which I hope I understand. No matter what kind of Exception is thrown, finally will execute and bring back an object to its intended state.



Correct.

When you have a finally block, then no matter how the try and catch portions complete--return, throw, break, continue, or normal completion--finally will be executed. That includes returning, throwing, etc. out of the catch blocks, not just the try.


One doubt Jeff - The return, continue, break keywords are intended to alter the flow control. Then why does the finally block still complete before any of these statements complete? (Unless of course I write a System.exit(0) call). Does it mean that internally, when the JVM encounters any of these 3 keywords, it first goes to finally block, regardless of whether is is a return statement, executes its contents and then returns to the caller method?


~ Mansukh
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Mansukhdeep Thind wrote:
One doubt Jeff - The return, continue, break keywords are intended to alter the flow control. Then why does the finally block still complete before any of these statements complete?


It doesn't complete before those statements do. But it executes before control is transferred to wherever it would normally go after those statements. And it's only if those statements would take us out of the overall try statement (which consists of the try block, the catch block, and the finally block). Finally doesn't come into it if, say, we're just continuing or breaking a loop inside the try block.

As for the reason that finally jumps into the flow of control that way, it's because the JLS says it does. Why does the JLS say it has to do that? Because the designers wanted to give us a way to execute clean-up code outside the normal happy path code, no matter how control is transferring out of the try statement.

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Throwing a RuntimeException