60
votes

I read this code where the interface throws an exception, but the class which implements it doesn't throw one or catch one, why is that? Is it legal or safe in java?

import java.rmi.*;
public interface MyRemote extends Remote {
    public String sayHello() throws RemoteException;
}

import java.rmi.*;
import java.rmi.server.*;
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote{
    public String sayHello() {
        return "Server says, 'Hey'";
    }
    public MyRemoteImpl() throws RemoteException {}
    public static void main (String[] args) {
        try {
             MyRemote service = new MyRemoteImpl();
             Naming.rebind("RemoteHello", service);
        } catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
}
3
You might want to check out the discussion at coderanch.com/t/399874/java/java/…Chetter Hummin
Yes it's legal. And you should see the link CHetter has posted, and he should also may be post it as an answer..Thihara
Interfaces is for declaring the methods. Here you have declared a method with name sayHello which has a String return type, and it will throw RemoteException. While defining it in the class, you do not need to re-specify that it throws the exception.Abhinav Kulshreshtha
Also according to LSP "No new exceptions should be thrown by methods of the subtype, except where those exceptions are themselves subtypes of exceptions thrown by the methods of the supertype."OldSchool
Yes, it is. In the interface you're saying: implementing classes MAY throw this exception. The other way around, though, is not legal, and will throw compile errors. The logic bhind is pretty simple: If you only know the superclass of a set of object, you should be able to handle exceptions and returns them properly. For instance, if you have a class Foo with a method getDuck() which reurns an objet of type Duck, you can declare getDuck() in any subclass of Foo with a return type BlackDuck, as long as BlackDuck is a subclassof Duck, since you coud handle it using Duck variables. Bad englishDGoiko

3 Answers

84
votes

A general rule of implementing and extending is you can make your new class or interface "less restrictive" but not "more restrictive". If you think of the requirement to handle an exception as a restriction, an implementation that doesn't declare the exception is less restrictive. Anybody who codes to the interface will not have trouble with your class.

— Stan James


As part of the discussion at http://www.coderanch.com/t/399874/java/java/Methods-throwing-Exception-Interface

24
votes

If a Java method overrides another in a parent class, or implements a method defined in an interface, it may not throw additional checked exceptions, but it may throw fewer.

public class A {
    public void thrower() throws SQLException {...}
}

public class B extends A {
    @Override
    public void thrower() throws SQLException, RuntimeException, NamingException {...}
}

SQLException is fine; it's declared in the overridden method. It could even be replaced by a subclass like SerialException.

RuntimeException is fine; those can be used anywhere.

NamingException is illegal. It isn't a RuntimeException, and isn't in A's list, even as a subtype.

9
votes

Great answer by @Chetter Hummin.

One way to look at this, and I find it easy to remember, is interface's implementations can be more specific but not more general.

For example in interface void test() throws Exception means "test may throw exception"

then implementation can be void test() means "test will not throw exception" (more specific)

or implementation can be void test() throws NullpointerException (more specific)

interface x {
    void testException() throws Exception;
}

public class ExceptionTest implements x {
    @Override
    public void testException() {   //this is fine
    }

    ////// or

    @Override
    public void testException() throws NullPointerException {  // this is fine
    }
}