AngryOliver
AngryOliver

Reputation: 397

Why can I declare a function without the "throws" keyword?

Consider the following code:

public interface I1 {
 public void bar1() throws IOException; 
} 

public interface I2 extends I1 { 
 public void bar2() throws Exception; 
} 

public interface I3 { 
 public void bar3() throws Exception; 
} 

public abstract class A implements I2 { 
 public void bar2() throws Exception{}; 
 public void bar3() throws Exception{}; 
 protected abstract void bar4(); 
 protected void bar5() {}; 
}

Now, I created a class, B as follows:

public class B extends A implements I3 {

    @Override
    protected void bar4() {}

    public void bar1()  {}

}

Why is the compiler letting me do that? I mean, shouldn't it be:
public void bar1() throws IOException;

Upvotes: 4

Views: 85

Answers (2)

vinayknl
vinayknl

Reputation: 1252

When overriding you cannot throw Broader or newer exception. Not throwing a super class method's exception is allowed.

The overriding method must NOT throw checked exceptions that are new or broader than those declared by the overridden method. For example, a method that declares a FileNotFoundException cannot be overridden by a method that declares a SQLException, Exception, or any other non-runtime exception unless it's a subclass of FileNotFoundException.

Upvotes: 1

Tim B
Tim B

Reputation: 41208

Inheritance lets you make functions more specific.

You can reduce the number of things you throw, you can return a subtype of the return type, you can accept a supertype of a parameter type.

This is because any possible call to your method most be a legal call to the super method, but the reverse does not need to be true.

In other words in your example:

new B().bar1() 

You know it doesn't throw the exception, you don't need to catch.

((A)new B()).bar1()

You need to catch the exception as since you are now processing any A or subclass of A you might need to handle it.

If you tried to do the reverse though and create a class C:

public class C extends A implements I3 {

    @Override
    protected void bar4() {}

    public void bar1() throws IOException, SomeOtherException {}

}

This would not be allowed as now if you tried to use a C as an A you are not going to be catching SomeOtherException.

Upvotes: 1

Related Questions