Reputation: 47
Consider a Java class hierarchy such as:
abstract class Exp { public void generate(); }
class EffExp extends Exp {...}
clas PureExp extends Exp {...}
class NewExp extends EffExp {...}
etc, etc.
The implementation of generate
inside NewExp
was changed to throw an IOException
.
public void generate() throws IOException {...}
The other implementations of generate
don't do any IO hence don't need to throw it. The compiler complains and forces me to declare all methods in the class hierarchy to throw the exception. Is this really the only way forward? It seems rather intrusive.
I could of course catch the exception where it happens, inside NewExp
, but that doesn't really make sense. The exception should propagate to the top and stop the program execution.
The more general question here is: if you have a hierarchy of methods that override each other, do they all have to be declared to throw the same set of exceptions?
Upvotes: 1
Views: 1770
Reputation: 61
We can not introduce a new checked exception in the overridden method but can have child checked exception or the same exception as handled in the parent class. Even if we do then if we refer to a child object with the parent reference it then compiler will force to catch the exception declared in the parent class method then look at the below example:
class Parent{
public void method throws IOException{
}
}
class Child extends Parent{
public void method throws SQLException{
}
}
class Test{
public static void main(){
Parent p=new Child();
try{
p.method();
}catch(IOException e){
e.printStackTrace();
}
}
}
In the above program, child class method throws SQLException but Compiler will force to catch IOException. Because at compile time it is not known to the compiler as child object is being referred from a parent reference. But we can declare any unchecked exception as compiler will not enforce try/ctach or throws for them.
Upvotes: 0
Reputation: 9260
Just consider this simple hypothetical code that, let's assume... fits your description:
Exp ex = new NewExp();
try {
ex.generate(); //It should throw an exception, but has no such method signature.
} catch(AnException e) { //Nope, not allowed.
...
}
Upvotes: 0
Reputation: 46
In abstract class you can define to throw java.lang.Exception
abstract class Exp { public abstract void generate() throws Exception; }
And in derived classes be more specific about what type of exception you throw.
Upvotes: 1
Reputation: 1249
Suppose the scenario is something like :
abstract class Exp { public void generate(); }
class EffExp extends Exp { public void generate throw IOException(....)....}
clas PureExp extends Exp {public void generate(....)....}
We use abstract class notation so that we could implement our other classes without worrying about the actual implementation . If we make actual; implementation narrowed i.e. throw Exception in some case and don't throw in some other case then its clearly a violation of Java being Robust. So you need to be clearly in sync. for all the methods.
Although you can increase the visibility by throwing a Parent "Exception".
Upvotes: 1
Reputation: 7854
If you are overriding a method, the overridden method in a superclass can only declare to throw that exception (checked) or its superclass. Otherwise you'll loose polymorphism and hence not allowed in Java
Upvotes: 0
Reputation: 213281
Just remember One Rule: -
Checked Exception
, decreasing the method visibility.So, if you have to (no choice), make your overriding method throw a Checked Exception
(Note that, you can add a unchecked Exception, though, but it wouldn't make any sense), just add the exception in the throws clause of the method you are overriding.
So, in simple words, the signature of your overridden
method should match exactly with the one that overrides it.
Now the simple reasoning behind this is - Polymorphism
.
In polymorphism, as you know that, you can have a super type
reference point to a sub class object. So, you can have: -
SupClass ref = new SubClass();
ref.method1();
Now, while checking for the existence of method1
, compiler is only concerned about the reference type. So, it checks in SupClass
, and allows the access accordingly.
Now, imagine what happens, when at runtime, when ref
is actually pointing to SubClass
object, JVM finds that method1
throws a new exception, that was not checked by the compiler
. It will crash. That is why it is not allowed.
Upvotes: 1
Reputation: 15552
Does it need to throw a checked exception. Could you wrap it in a runtime exception?
public void generate() {
try {
....
} catch (IOException e ){
RuntimeException re = new RuntimeException();
re.initCause(e);
throw re;
}
}
(not checked this for compilation but it should give you a general idea
Upvotes: 0