Mandark
Mandark

Reputation: 828

Removing throws in overriden method, compiler wants a try/catch block when invoking

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

Answers (3)

AlexR
AlexR

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

Stephen C
Stephen C

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

Johan Sjöberg
Johan Sjöberg

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

Related Questions