• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Throwing a RuntimeException

 
Ranch Hand
Posts: 117
Mac Chrome Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 117
Mac Chrome Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


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
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Master Rancher
Posts: 4806
72
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 117
Mac Chrome Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you both, Jeff and Mike. That cleared things up a bit.

 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome!
 
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.

 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic