• 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

Exam Watch on page 108 of the SCJP K&B book

 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
On page 108 of the SCJP book by K & B Exam Watch states: "If a method is overridden but you use polymorphic behavior (supertype) reference to refer to the subtype object with the overriding method, the compiler assumes you're calling the supertype version of the method." This does not make sense because the the when overridding a method the one that gets invoked is the subtype object instance NOT the supertype. Correct? Please explain as I have been trying to figure this line out for the past four hours.

Then it states: "If the supertype version declares a checked exception, but the overridding subtype method does not, the compiler still thinks you are calling a method that declares an exception. Let's take a look at an example:

class Animal {
public void eat() throws Exception {
// throws an Exception
}
}

class Dog2 extends Animal {
public void eat() { /* no Exceptions */ }
public static void main (String [] args) {
Animal a = new Dog2();
Dog2 d = new Dog2();
d.eat(); // ok
a.eat(); // compiler error unreported exception
}
}

This code will not compile because of the Exception declared on the Animal eat() method. This happens even though, at runtime, the eat() method used would be the Dog version, which does not declare an exception."

I have a hard time understanding the very first line as well the exceptions. Why does the subtype (in this case Dog2) method need to have an throws Exception in order for the line with a.eat() complie correctly? I would appreciate if you could sense of this for me.
 
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are two parts of a method invocation of type <reference>.<method>:
- Compile time: At this point, the compiler looks at the type of <reference>, and finds the <method> defined in that class. In other words, at compile time you only have the starting point of the override chain (the compiler leaves determining the actual method to the JVM at runtime. The actual method invoked at runtime might be different from the method determined at compile time when the method is overridden by a subclass.)
- Runtime: When the method is called at runtime, the JVM looks at the actual type of the object that <reference> points to. If this class is in an inheritance branch which overrides the method determined at compile time at some point, then that method will be called. In other words, the JVM, starting at the actual type of the object, travels up the inheritance branch towards the type of the reference, and stops when it finds the first overriding definition of <method>.

The problem is that at compile time, the compiler only knows that the <method> is the one defined in the type of <reference> or one of its derived types, so it has to enforce the rules so that even in the worst case scenario (when <method> is the one defined in the type of <reference> the restrictions of checked exceptions are observed.

In simple terms, from the point of view of the compiler, when you call a.eat(), it thinks that eat() might be the eat() defined in Animal, which throws a checked exception.
 
Christian Lombardo
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When you say "has to enforce the rules so that even in the worst case scenario (when <method> is the one defined in the type of <reference> the restrictions of checked exceptions are observed." The rules as I understand from the K&B book are:
*Overriding method must not throw checked exceptions that are new or broader than those declared by the overridden method.
* Overriding method can throw narrower or fewer exceptions. Just because an overridden method "take risks" does not mean overriding subclass exception takes same risks. Bottom line: an overriding method does not have to declare any exceptions that it will ever throw regardless of what the overridden method declares.

How does these rules in the K&B book coincide with this example and what you are saying? Are there other rules "overriding + check exceptions" I do not know about? If so Could you please explain.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Christian Lombardo wrote:When you say "has to enforce the rules so that even in the worst case scenario (when <method> is the one defined in the type of <reference> the restrictions of checked exceptions are observed." The rules as I understand from the K&B book are:
*Overriding method must not throw checked exceptions that are new or broader than those declared by the overridden method.
* Overriding method can throw narrower or fewer exceptions. Just because an overridden method "take risks" does not mean overriding subclass exception takes same risks. Bottom line: an overriding method does not have to declare any exceptions that it will ever throw regardless of what the overridden method declares.

How does these rules in the K&B book coincide with this example and what you are saying? Are there other rules "overriding + check exceptions" I do not know about? If so Could you please explain.


What I meant is that if you have a method call which may throw a checked exception you must either catch the exception or declare it in the method enclosing the call.
 
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You have to understand one thing: Compile time and Run Time

At Compile time, the only thing the compiler does is to check a if the reference type and what is referring to have a parent-child relationship. (hi Ruben I apologize if I'm missing any other task that the compiler does , but please let me know if I'm missing something important!)
So you still have to follow the header of super method. So let if the super method throws a checked exception , you must catch it or declared in the current method. Also another gotcha is in covariance return, for example:
A code created by me:

At run time is where overridden happens, and it will choose the sub class method.

 
armando fonseca
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
m
 
Christian Lombardo
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for all your responses!

One thing I am a bit confused about when you look at the original example in this post is the exceptions. Since the compiler only checks the reference at compile time then why does it still throw an unreported exception when you run a.eat() on line 13? The exception IS declared on the reference type which is the supertype Animal. So why the compiler complains about unreported error on a.eat(); line if the exception IS declared in the reference supertype Animal method eat() on line 2?

 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The exception is reported in Animal.eat(), which means the compiler knows that when that method is called, a checked exception might be thrown. That's why, when you call that method anywhere else (as you are doing in Dog2.main(),) you either need to declare the checked exception in Dog2.main(), or put it in a try block. At every single point that a checked exception might be thrown, you either need to declare it in the enclosing method, or put it in a try block.
 
Ranch Hand
Posts: 430
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Christian Lombardo wrote:Why does the subtype (in this case Dog2) method need to have an throws Exception in order for the line with a.eat() complie correctly?


Who said it to you? You will still have compile error, but now two.
Just keep in mind that the compiler doesn't know that the Animal's reference variable is referencing an subclass or the class itself.
The compiler only knows that the Animal's reference variable is referencing an animal.
 
Christian Lombardo
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you very much!

I plan to take the SCJP in July. I have been studying 8 - 12 hours a day for this with the book: Sun Certified Programmer for Java 6 Study Guide by Sierra and Bates.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic