This week's book giveaway is in the OCAJP forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide 1Z0-808 and have Jeanne Boyarsky & Scott Selikoff on-line! See this thread for details.
There seems to be a difference in how subclasses and overloading are handled between normal classes and exceptions. Here's some sample code:
For normal subclasses being passed to an overloaded method, the method that matches the parameter's reference type is used. (eg, the variable pc is a reference type Parent pointing to a Child object, and it calls the method with signature m(Parent)). However, with subclassed exceptions it seems to be opposite. e3() declares that it throws a SuperException, but in actuality it throws a SubException (which seems fine because a reference to a super class is being used to point to a sub class). But, when it comes to the catch block, it is caught as type SubException. Why the automatic type cast? I'm assuming that the exception is handled by the very first catch that can possibly handle it, but given that it is different than how overloaded methods are handled it seems odd.
use the [CODE] tags - it makes it much easier for people to help you.
Jon, I think you're trying to compare two things that really aren't alike. First of all, let's look at what happens when we have a method invocation expression. Let's use this example code:
Notice that I've only defined a method that takes a Child as an argument. In my main method, I'm invoking the method m and passing it a Child object, but it is being referenced by a Parent variable. This causes a compiler error because the class test2 has no applicable methods for the method invocation expression test2.m(p). Obviously, no implicit conversion is taking place in this case. When we look at catching exceptions, on the other hand, we put a little different spin on things. Now, a conversion can take place. At each catch block, the JVM asks itself, "Is the exception that was thrown of type X?" It's important to remember that when we define an inheritance relationship, we are essentially saying that the subclass "is a" superclass. In your example, SubException "is a" SuperException. Therefore, if the JVM has a SubException and it finds a catch for a SuperException, the JVM says to itself, "Yup. The SubException that was thrown is a SuperException" so it proceeds with that catch block. Based on that, you can see that inheritance for exceptions is really no different from any other object. They still have the same "is a" relationship that any other Java objects would have - exceptions are Java objects in themselves. The problem here is that you're comparing two things, method invocation and exception handling, that are not performed in the same way. The inheritance is the same, but the operations you're looking at aren't. I hope that helps, Corey
Corey, Thanks for the explanation. It just caught me off guard, because exceptions will be caught by the first possible match, where as overloaded methods seem to go with the bets possible match (ie, a Parent reference to a Child object will use the method that has Parent as a parameter). Just one more thing to keep in mind for the exam. -Jon