This week's book giveaway is in the OCPJP forum. We're giving away four copies of OCA/OCP Java SE 7 Programmer I & II Study Guide and have Kathy Sierra & Bert Bates on-line! See this thread for details.
I'm reading K & B 1.5 SCJP Certification text. Can you clarify a portion of the text which seems contradictory?
The overriding method can throw narrower or fewer exceptions. Just because an overridden method "takes risks" doesn't mean that the overriding subclass exception takes the same risks. Bottom line: an overriding method doesn't have to declare any exceptions that it will never throw, regardless of what the overridden method declares. (PAGE 102-103)
If a method is overridden but you can use a polymorphic (supertype) reference to refer to the subtype object with the overriding method, the compiler assumes you're calling the supertype version of the method. If the supertype version declares a checked exception, but the overriding subtype method does not, the compiler still thinks you are calling a method that declares an exception (more in Chapter 5). Let's take a look at an example: (PAGE 104)
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 the exception. (PAGE 104)
In the example quoted above the overriding method in the Dog2 subclass doesn't declare an exception that it will never throw, even though the overriden eat() method in Animal declares the exception. The Dog2 subclass is taking "greater risks" by not declaring the exception, but the eat() method in the Dog2 subclass will never throw an exception. I may be splitting hairs, but I'm interested in anything which will clarify my understanding. Thanks.
Thanks Ken. This is the quote from your exception thread.
Bob Ruth wrote:Because the reference declared is a sup reference (superclass) and it is handed a reference to a test (subclass) object, polymorphism is in play. When the is the case, the compiler is going to require that you construct the code to handle each possible type of object whether YOUR code does it or not. The compiler isn't going to assume that the super reference will ONLY hold the subclass type....rather, it will have you code the try catch block so that either object could be put into the reference.
I think I understand that the IS-A relationship between the subclass and the superclass objects isn't maintained unless the method signatures of subclass methods are the same as the method signatures of superclass objects. The K&B text doesn't say this. Without inheritance, there can't be any overriding/overridden methods. I'm clear on the fact that inheritance is not synonymous with polymorphism, but polymorphism is one of the prime reasons that inheritance is implemented. One of the prime reasons that overriding/overridden methods are implemented is so that they can be invoked polymorphically. The quoted text seems to me to be WRONG.
There isn't any clarification in the K&B errata
On PAGE 111 of the K&B 1.5 Certification text, it says the following in Table 2-3:
Overridden Method - Exceptions - Can reduce or eliminate. Must not throw new or broader checked exceptions.
Joined: Jun 17, 2009
There are typos in the original code snippet. I tried compiling this snippet on a Java 6 compiler and it reported the following error:
Dog2.java:13: unreported exception java.lang.Exception; must be caught or declared to be thrown
a.eat(); // compiler error -
Joined: Jun 17, 2009
The following code snippet compiles without any problem. This solution is in agreement with the book. What is the explanation for this behavior is the question that I would like to have an answer for?
Joined: Jun 17, 2009
I understand the reason now.
At compile time, the compiler doesn't know if the 'a' reference is referring to a Dog2 object or an Animal object. This will not be determined until runtime. Since the reference type of 'a' is Animal, the compiler assumes that the a.eat() method invocation is on an Animal object. The main() method must either throw an Exception exception object in its method declaration or it must 'catch' an Exception exception object when invoking the a.eat() method. That is it must 'Duck or Catch' the exception thrown by the Animal class a.eat() method. The compiler doesn't know that the Dog2 eat() method is invoked polymorphically, because this happens at runtime. The compiler only knows that the a.eat() method is invoked on an Animal reference at compile time. The compiler enforces the 'Duck or Catch' requirement for exception handling.
The following code also compiles without an error.