The following two pieces of code have a different outcome. Please help me understand why
Code 1 would throw a compilation error on line 19 while code 2 would not on line 18. As far as I understand both the "process()" methods in class B should be handled in a try/catch as the super method throws an Exception. Then why does Code 2 compile and run fine while Code 1 does not ?
In code1, you have clearly declared variabel 'a' to be of type A.
So, when the compiler reaches line 19 in code 1, it is fooled into thinking that the process() method that is being called is of class A. So, it expects that the method should be surrounded with a try catch block.
It is only at runtime that the the JVM decides the actual method that is to be called, which in the case of code 1, will be the overridden method process() of class B.
In code2, the pseudo object that you have created is of class B.
Since there is no trace of any reference of class A, the compiler 'KNOWS' that the method that will be called is of class B, which throws no exception.
To sum up,
When calling a method, the compiler checks the type of the reference to determine the class whose method will be called.
Whereas at runtime, the actual type of the object, pointed to by the reference, gets called. The compiler, at any given point of time, is not aware of the actual object. For it, its the reference type that is of the utmost importance.
Since you are new, I shall add code tags to your post, so you can see how much easier it is to read.
Thank you for the clarification. The b.process() in both the codes overrides a.process(). Doesn't it mean that b.process() 's is also expected to throw a Exception ? In which case, try/catch is required for Code 2 too ? Its obvious I missed something here.
Thanks Ritchie for the code tag. Will follow it from my next post.
Midhun Agnihotram wrote:The b.process() in both the codes overrides a.process(). Doesn't it mean that b.process() 's is also expected to throw a Exception ? In which case, try/catch is required for Code 2 too ? Its obvious I missed something here.
No, because B.process explicitly says it will throw no checked exception at all. By using "new B()" the compiler knows that the type is not A but B, and that you are calling B.process. That does not throw any checked exceptions so the compiler doesn't expect any.
even if the overridden method does. Here's why.
Assume that the super-class is already being used somewhere. This
implies that its thrown exceptions are being handled properly. Now a
sub-class with an overriding method arrives on the scene, eliminating
the need for an exception. So it does not need to be thrown.
If the overriding method does throw exceptions, however, there is a
rule to follow. Each thrown exception must be the same class, or a
sub-class, of the thrown exceptions in the overridden method. For
example, if Except is thrown by the super-class method, then MyExcept
(extends Except) may be thrown by the overriding method. This makes
sense because older code that catches Except will also catch MyExcept.
... Jim ...