Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

K&B Test 6, Q13. Exceptions

 
nick woodward
Ranch Hand
Posts: 370
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


The answer says that this code fragment will compile, as does some messing with code.

However I got the answer wrong, on the basis that try blocks must be able to throw the type of Exception specified in the catch block (so I thought the compiler would complain).

I assume I'm wrong because Exception could be RuntimeException? Replacing the catch block with a more specific checked exception gives the answer I would've expected.

oh, and as an aside - question 15 has me worried about the semantics of the questions (it references an IOException without import or qualification as an answer). Are there any particular nuances that occur with the question wording ('given', 'code snippet', 'code fragment' etc) that I should be wary of? I don't know why, but that question really rubbed me up the wrong way!

Thanks,

Nick
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:However I got the answer wrong, on the basis that try blocks must be able to throw the type of Exception specified in the catch block (so I thought the compiler would complain).

I assume I'm wrong because Exception could be RuntimeException? Replacing the catch block with a more specific checked exception gives the answer I would've expected.

That's indeed correct! Using this catch clauseyou can handle an (unhandled) runtime exception thrown in the go() method. For example

nick woodward wrote:oh, and as an aside - question 15 has me worried about the semantics of the questions (it references an IOException without import or qualification as an answer). Are there any particular nuances that occur with the question wording ('given', 'code snippet', 'code fragment' etc) that I should be wary of? I don't know why, but that question really rubbed me up the wrong way!

A few months ago Oracle added some assumptions to the beginning of the exam objectives. So that's definitely a must read (the first one is about missing package and import statements )

Hope it helps!
Kind regards,
Roel

PS. The code snippet you have posted does not compile. Let's see if you can spot the issue yourself, just like if it were an actual exam question
 
nick woodward
Ranch Hand
Posts: 370
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Roel,

just to make sure - i'm clear that the catch clause is able to handle runtime exceptions, what i was unclear about was the rule that the try block has to be able to throw the exception described in the catch clause. In the case where catch has 'Exception' as the argument, this rule doesn't apply, because any code can throw an unchecked exception, therefore the try block always has the ability to throw a subclass of Exception. (whereas with something like java.io.IOException you'd have to have an explicit throw or call to a method that declares that exception to be thrown)

Correct?

And thanks for that link. Good to know. And good job I ignored question 15 when marking my work (......browses K&B errata thread..... ) In all seriousness though, I won't forget that now!

Thanks,

Nick


*edit... does it not compile? hang on, give me a sec, it looks like it does
** It's not the class name, it's not the main declaration, the try and catch block look ok, Exception doesn't need an import, brackets seem ok. new Gotcha.go() isn't normally how I'd call a method, but looks ok, and means go doesn't have to be static. And the compiler is too stupid to see the stackoverflow problem.

I'm so tempted to try and compile it.....(i won't) it must be new Gotcha.go();

**yup. i'm an idiot! new Gotcha().go();
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:*edit... does it not compile? hang on, give me a sec, it looks like it does

Of course! Otherwise I would not mention it You should know by now that I am the personification of a Java compiler

nick woodward wrote:I'm so tempted to try and compile it.....(i won't) it must be new Gotcha.go();

That's indeed the statement which results in a compiler error And if you are preparing for the OCPJP certification exam in the coming months, I'll just ask you to add this code to the Gotcha class in order to make the original code snippet compile
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:And the compiler is too stupid to see the stackoverflow problem.
...
**yup. i'm an idiot! new Gotcha().go();

I think the compiler now thinks something like "If I'm too stupid, why does he need/use me to spot such an obvious compiler error"
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:what i was unclear about was the rule that the try block has to be able to throw the exception described in the catch clause. In the case where catch has 'Exception' as the argument, this rule doesn't apply, because any code can throw an unchecked exception, therefore the try block always has the ability to throw a subclass of Exception. (whereas with something like java.io.IOException you'd have to have an explicit throw or call to a method that declares that exception to be thrown)

Correct?

Yes, you are correct! The Exception class is a checked exception, so if you invoke a method like this oneyou'll need to handle or declare the (checked) Exception; otherwise you'll get a compiler error.
If you use a checked exception in a catch handler, the compiler will also check/verify if the checked exception could be thrown from the try block. If that's not the case, the compiler will complain and give you a compiler errorBut if you use the (checked) Exception class as a catch handler, the compiler does not complain anymoreThe reason is very simple: using this catch handler you can handle runtime exceptions which might be thrown by the klm() method.

Now it's time again for a famous pop quiz question What do you think will happen if you try to compile the following code snippets? And like always: it's a good thing if you have the correct answer, but it's even better if you can give the correct reason

Hope it helps!
Kind regards,
Roel
 
nick woodward
Ranch Hand
Posts: 370
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel De Nijs wrote:
nick woodward wrote:*edit... does it not compile? hang on, give me a sec, it looks like it does

Of course! Otherwise I would not mention it You should know by now that I am the personification of a Java compiler



Roelpiler? comproeler?

Roel wrote:
"If I'm too stupid, why does he need/use me to spot such an obvious compiler error"

its my way of remembering that it doesn't run code. stupid compiler

(i understand why it doesn't, this way is more amusing so i remember it better)
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:Roelpiler? comproeler?

Because my first name in Dutch is pronounced exactly like the English "rule" and a compiler has to verify a Brobdingnagian set of rules, I prefer roelinator
 
nick woodward
Ranch Hand
Posts: 370
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
abc() fails because it isn't possible to throw an IOException in the try block (although I'm tempted to say it's ok because the declared exception in abc() is the superclass of IOE - but i'm pretty sure that's wrong, IOException is still pointless)

klm() fails for the same reason. klm throws no checked exceptions, so IOException is the problem. the catch clause with Exception is fine because klm() could throw a runtime exception.

?

but these are very similar answers...... so i've probably missed something!

(i dunno, comproeler sounds even better if your name is pronouced that way. sounds like you rule the compiler)

 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:abc() fails because it isn't possible to throw an IOException in the try block (although I'm tempted to say it's ok because the declared exception in abc() is the superclass of IOE - but i'm pretty sure that's wrong, IOException is still pointless)

Unfortunately that's incorrect! The tuv() method compiles successfully And I think you'll know why if you think about it, so I'm not yet providing the reason why.

nick woodward wrote:klm() fails for the same reason. klm throws no checked exceptions, so IOException is the problem. the catch clause with Exception is fine because klm() could throw a runtime exception.

Spot-on! (although you probably mean wxy() fails to compile for the same reason as there's nothing wrong with the klm() method)

nick woodward wrote:sounds like you rule the compiler

I wish
 
nick woodward
Ranch Hand
Posts: 370
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ah, ok!

so the declaration in abc() isn't saying it *will* throw Exception, it's saying it'll throw anything up to Exception.

i wanted to blame it on the stupid compiler, but it was probably me that time......

 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:so the declaration in abc() isn't saying it *will* throw Exception, it's saying it'll throw anything up to Exception.

Indeed! A throws clause indicates the method could throw that exception or any of its subclasses.

But why does the tuv() method compiles successfully?
 
nick woodward
Ranch Hand
Posts: 370
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel De Nijs wrote:
nick woodward wrote:so the declaration in abc() isn't saying it *will* throw Exception, it's saying it'll throw anything up to Exception.

Indeed! A throws clause indicates the method could throw that exception or any of its subclasses.

But why does the tuv() method compiles successfully?


because the Exception catch clause mops up anything thrown that isn't an IOException (because abc() can throw exceptions that are broader than IOE), and IOE is allowed because it's a subclass of Exception and therefore contains the code to deal with a specific type of Exception that abc() could throw. Namely IOE or FNFE

?

 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:because the Exception catch clause mops up anything thrown that isn't an IOException (because abc() can throw exceptions that are broader than IOE), and IOE is allowed because it's a subclass of Exception and therefore contains the code to deal with a specific type of Exception that abc() could throw. Namely IOE or FNFE

Exactly! Because abc() can throw Exception or any of its subclasses, it could potentially throw an IOException. And therefore you can have a specific catch handler for IOException (and its subclasses), because you might want to handle these exceptions differently than all other exceptions.

As we are having so much fun here, let's continue with a bunch of other (free) mock questions. Because I'm out of letters, I had to use z with an index The question is exactly the same as the previous pop quiz: what do you think will happen if you try to compile the following code snippets? And why?

Hope it helps!
Kind regards,
Roel
 
nick woodward
Ranch Hand
Posts: 370
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
z1:

i think the IOException catch clause is fine - it deals with the FNFE declared by z0 (although I'm still unsure why it wouldn't complain that IOE can't be thrown?)
Exception catch clause is fine - it deals with the NullPointerException
but I think the custom exception is a problem and it won't compile. z0 doesn't throw it, or anything related to it

z2:
I think the IOException causes a problem here. FNFE is dealt with by the relevant catch clause, and the NPE by Exception, but the IOException is never thrown and can never be. FNFE IS-A IOException, but I don't think that is good enough.

z3
This one I don't know. I'd guess NPE and RuntimeException being the wrong way around could cause an issue, but equally you don't even have to handle them, so the compiler likely doesn't care.
The same is sort of true about the Exception catch clause and the runtime catch clause. Are you allowed both when the runtime catch renders the Exception catch irrelevant? I'd guess this isn't ok if push came to shove.......

 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:z1:

z1 will indeed not compile. And your explanation is spot-on. The reason why the compiler doesn't complain about IOE is simply because FNFE IS-A IOE and you are allowed to have a catch handler for a broader exception.

i think the IOException catch clause is fine - it deals with the FNFE declared by z0 (although I'm still unsure why it wouldn't complain that IOE can't be thrown?)
Exception catch clause is fine - it deals with the NullPointerException
but I think the custom exception is a problem and it won't compile. z0 doesn't throw it, or anything related to it

nick woodward wrote:z2:

Incorrect! z2 compiles successfully. The catch handler for IOE is an unreachable catch handler and results in a compiler warning but not in a compiler error


nick woodward wrote:z3:

z3 will not compile! The compiler doesn't verify if a runtime exception is handled or declared (like checked exceptions). But that's completely unrelated with the fact of the order of the catch handlers. That's the same for all different exceptions and errors. And as you probably know in order to have valid syntax, the order of the exceptions in the same class hierarchy used in the catch handler is important. The subclass must come before the superclass. The order of unrelated exception classes is not important. So if you check the order of the exceptions used in the catch handlers, you'll notice that RuntimeException is before NullPointerException and because NullPointerException IS-A RuntimeException, it is not allowed by the compiler and you'll get a compiler error. If you would move the catch handler for NullPointerException in front of the catch handler for RuntimeException, the z3 method will compile successfully.
In this method you'll have two hierarchies of exception classes:
1/ NullPointerException - RuntimeException - Exception
2/ IOException - Exception
So in order to have valid syntax you can't change the order of the catch handlers within each class hierarchy. But different hierarchies can be combined as you like. So this is another method which compiles successfully

Hope it helps!
Kind regards,
Roel
 
nick woodward
Ranch Hand
Posts: 370
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
apologies Roel, I do appreciate the reply, i'm going to get back to this shortly!
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:i'm going to get back to this shortly!

Luckily "shortly" is a very subjective term
 
nick woodward
Ranch Hand
Posts: 370
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
so much fun it only seems like yesterday Roel!

yeah, sorry about that. at least now i get to try these again (i re-read the thread, but not the latest answers /corrections this time around). let's see if i'm better the second time.....

Roel De Nijs wrote:


ok. so I'm struggling a litte with the rules to apply, but:
NPE is caught, along with all other runtime exceptions, by the Exception block.
FNFE is dealt with by the superclass IOException
CustomException causes a compiler error.

Roel De Nijs wrote:


if memory serves, i got this one wrong. and i'd still get it wrong today.
Exception block deals with runtime exceptions potentially thrown
FNFE block deals with the related exception thrown by z0
IOException is unnecessary - I would still say this *should* cause an error (but I'll look at your explanation after this post)

Roel De Nijs wrote:

the order of catch blocks is wrong for the runtime exceptions. also the Exception catch block is now pointless, because the runtime exceptions it was catching are now dealt with earlier in the RTE block.

now let me go and look at your response to my last effort!

thanks,

Nick
 
nick woodward
Ranch Hand
Posts: 370
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ok, so pretty much identical answers.

it seems like my problem is that a try block must be able to throw the exception, but that
you are allowed to have a catch handler for a broader exception.

to me that seems like the try block can't throw the superclass, and should therefore not compile. for example


complains because no IOException can be thrown.


but equally only a subclass of IOException can be thrown. - i suppose *technically*, it is throwing the superclass, just in the form of a subclass.

i guess if that only causes a warning by the compiler, i can remember that.

so basically, if the a catch block is "unreachable", because it's preceded by a subclass block, and only that subclass is thrown, you get a warning. if the exception, or its subclasses are never thrown, it won't compile.

so in z0 - if we ignore the runtime exception order (or fix it), the compiler should warn us about the Exception block (and the Runtime block, if the order was corrected.). am going to go try this out!

nick



 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:NPE is caught, along with all other runtime exceptions, by the Exception block.
FNFE is dealt with by the superclass IOException
CustomException causes a compiler error.

Spot-on! But one small (important) note: NPE is a runtime exception, so it doesn't matter (for the compiler) if it's handled or declared. It's only important for a gracious execution of your code that a runtime exception is handled by a catch block, otherwise this exception would blow up in the user's face (which you probably want to avoid).

nick woodward wrote:if memory serves, i got this one wrong. and i'd still get it wrong today.
Exception block deals with runtime exceptions potentially thrown
FNFE block deals with the related exception thrown by z0
IOException is unnecessary - I would still say this *should* cause an error (but I'll look at your explanation after this post)

As you have noticed from my explanation: this code compiles successfully although the (checked) IOException is not thrown from within the try block, but a subclass is thrown and this subclass is already handled by a previous catch handler.

nick woodward wrote:the order of catch blocks is wrong for the runtime exceptions. also the Exception catch block is now pointless, because the runtime exceptions it was catching are now dealt with earlier in the RTE block.

Indeed! So the compiler doesn't verify if runtime exceptions are handled or declared. But if you use any catch handlers, the order of the exceptions in the same class hierarchy is important. The subclass must come before the superclass.

Hope it helps!
Kind regards,
Roel
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nick woodward wrote:i guess if that only causes a warning by the compiler, i can remember that.

I can see why you are confused about this specific case. I also have no clue why this case isn't addressed in the reachability rules (warning: link to the JLS, read at your own risk ). That's something you'll probably need to ask the Java designers. It might require a significantly more complicated formulation of the reachability rules to handle every possible use case (our example is pretty simple: one subclass and its superclass) and having a very complex specification could be a concern.

nick woodward wrote:so basically, if the a catch block is "unreachable", because it's preceded by a subclass block, and only that subclass is thrown, you get a warning. if the exception, or its subclasses are never thrown, it won't compile.

Remember that this custom "nick" rule only applies to checked exceptions! For runtime exceptions you only have to care about the order of the catch handlers (if the runtime exceptions belong to the same class hierarchy). But the idea behind this rule is correct! If a checked exception is thrown from within the try block, you can have catch handlers for this exception, its subclasses and its superclasses without the compiler complaining (and giving a compiler error), if of course the order of the catch handlers is flawless! Here's a code snippet which compiles successfully

nick woodward wrote:so in z0 - if we ignore the runtime exception order (or fix it), the compiler should warn us about the Exception block (and the Runtime block, if the order was corrected.). am going to go try this out!

Let's fix the order of the catch handlers for the runtime exceptions and see what happensThis code compiles successfully without any warnings! Again, the compiler is not interested in runtime exceptions at all. And because the compiler doesn't know if a given runtime exception could be thrown from within a try block, it will definitely not flag any catch handlers of runtime exceptions. The compiler will simply ignore them. But it does verify the order of the catch handlers. And that applies to all exceptions and Errors!

Hope it helps!
Kind regards,
Roel
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic