Reputation: 828
I have a subclass and I am overriding the inherited parent method: I am removing the throws clause from the method declaration.
Now, using polymorphism, the my instance's runtime type should determine the method implementation; yet, the compiler complains and wants a try/catch block around the method invocation when I try to compile, as if the superclass method is being invoked and not the subclass version?
I'm aware that I can remove the throws declaration or narrow down the checked exception which can be thrown when overriding. Why is this still throwing the exception?
class A{
void foo()throws Exception{throw new Exception();}
}
class SubB extends A{
@Override
void foo(){ System.out.println("B");
}
public static void main(String[] args) {
A a = new SubB();
a.foo(); //compiler reports: unhandled exception type Exception
}
Upvotes: 3
Views: 1583
Reputation: 115338
Compiler is right. The line
A a = new SubB();
"Means "create instance of class SubB
and assign it to variable of type A
".
This means that from this point the variable a
's type is A
, not SubB
. But foo()
defined in A
throws unchecked Exception that must be re-thrown or caught by caller. This is what compiler tells you.
At line
a.foo()
compiler already "does not know" that the real instance type is SubB
. It treats it as A
.
Upvotes: 1
Reputation: 718826
That has happened because assigning the SubB
instance to a
removes the knowledge that the instance is a SubB
. As an A
, a.foo()
can now (as far as the JLS is concerned) throw Exception
.
Compile-time type knowledge is based on the declared types of the variables rather than any (hypothetical) inferred types if the variable contents.
Upvotes: 1
Reputation: 49187
The compiler ses an A
which does throw an Exception. If you however told the compiler it's an actual SubB
object it will stop complaining
SubB b = new SubB();
b.foo();
Upvotes: 7