• 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:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Overridden method and exceptions

 
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm not sure I understand this concept well enough. In Chapter 5 of the SCJP 5 book (yes, I have access to v. 6 as well) question 8 asks:

Given:
And the following three possible changes:
C1. Declare that main() throws an exception
C2. Declare that Ping.getInt() throws an exception
C3. Wrap the invocation of getInt() in a try/catch block

Which change(s) allow the code to compile? (Choose all that apply)
A. Just C1
B. Just C2
C. Just C3
D. Both C1 and C2 are required
E. Both C1 and C3 are required
F. Both C2 and C3 are required
G. All three changes are required.

I got the answer wrong, so tried out the example for myself. My understanding is:
A. Since Ping extends Utils and Ping.getInt() has the same signature as Utils.getInt(), getInt() is an overridden method
B. Overridden methods are determined by the actual object (Ping) at runtime
C. Overridden methods can throw the same, less restrictive, or no exceptions

Therefore, the compiler shouldn't care that Ping.getInt() doesn't throw any exceptions... right? But it does.

Where am I mistaken?

BTW, the book says that only A and C are correct, yet if you take the statement "What changes allow the code to compile? Choose all that apply" at face value, answers D, E, F, and G are also true.
 
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The cue here is that your variable is of type Utils, hence at compile time the compiler cares about the signature of the getInt method in Utils and not in Ping. Thus you have to handle the exception. If you declared 'u' as Ping, then there is no reason to handle the exception, since the overridden form is in force.
 
richard rehl
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hm... I thought that the rules were that

A. the reference variable determines which overloaded method is used at compile time
B. the actual object determines which overridden method is used at runtime.

But you've just stated a third rule, it would seem, that I didn't find obvious in the book.
 
Sebastian Janisch
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is no third rule, the rule is part of A ;)
 
richard rehl
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Arghhh! But this is an overridden method, not an overloaded one, right???
 
Ranch Hand
Posts: 423
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

richard rehl wrote:
Therefore, the compiler shouldn't care that Ping.getInt() doesn't throw any exceptions... right? But it does.


Compiler cares only about things declared at compile time - it doesn't care about things that may happen during runtime.
Variable 'u' is declared as of type of Utils.
Method getInt in class Utils is declared that throws Exception.
So compiler knows that invocation of form u.getInt() may throw checked Exception,
and therefore force you to catch this exception (answer C) or to declare that main throws this exception (answer A).
It doesn't matter that in this code 'u' will reference only object of class Ping and will never reference
object of class Utils. You know this because you are smart enough to analyse code and predict that this will never happen.
Compiler is not so smart - it cannot analyse what code will do, and makes it's decision only on declarations.

richard rehl wrote:
BTW, the book says that only A and C are correct, yet if you take the statement "What changes allow the code to compile? Choose all that apply" at face value, answers D, E, F, and G are also true.


D,E,F and G say: "both .... are required"
Since A either C are sufficient to allow code to compile, so both are not required.
 
richard rehl
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, so let me get this straight. Even though overridden methods may throw narrower or fewer exceptions, if the superclass method throws a checked exception, and there's a superclass reference to a subclass object, and that reference calls the overridden method, the subclass method then must throw the same exceptions?
 
Ireneusz Kordal
Ranch Hand
Posts: 423
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

richard rehl wrote:OK, so let me get this straight. Even though overridden methods may throw narrower or fewer exceptions, if the superclass method throws a checked exception, and there's a superclass reference to a subclass object, and that reference calls the overridden method, the subclass method then must throw the same exceptions?


Strictly speaking, methods don't must throw exceptions, they may throw exceptions.
The subclass method throws fewer exception .... but this fewer exception is an object of a class that is a subclass of wider exception, so we could say that wider exception is thrown even if this is fewer exception .....
Look at this example:

Variable 'a' is declared as 'A' - method ping() in a superclass A is declared that may throw IOEXception.
Variable 'a' holds reference to an object of subclass B - method ping() in this subclass is declared that may throw FileNotFound exception.
FileNotFound exception is a subclass of IOException, so code compiles fine (FileNotFound is fewer and IOException is narrower).
If you run this code, you'll get this stack trace:

At runtime FileNotFoundException exception was thrown.
But FileNotFoundException is a subclass of IOException, so we could say that IOException was thrown (FileNotFoundException is a IOException).
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic