Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface Declaration with Unchecked vs. Checked Exceptions

I've searched for a potential answer to my question below, and have not found one.

I understand the difference between checked and unchecked exceptions as well as what the programmer can/must do with them. However, I don't quite understand how the compiler interprets unchecked exceptions when it comes to interfaces.

Recently, I was programming an interface and implementation similar to the following:

public interface Operation {
    int operate(int x, int y) throws ArithmeticException;
}

public class Divide implements Operation {
    @Override
    public int operate(int x, int y) throws ArithmeticException {
        try {
            return x / y;
        } catch (ArithmeticException ex) {
            System.out.println("Division error!");
        }
    }
}

Here's where I'm confused. The following implementation will also compile:

public class Divide implements Operation {
    @Override
    public int operate(int x, int y) {
        return x / y;
    }
}

Why does the compiler not care that I have declared the method as throwing an exception in the interface? I understand that Unchecked Exceptions are Runtime Exceptions and that it is not required that the programmer handle them, but do not understand why when I explicitly state in my interface that I want the exception handled that it does not force me to handle it.

Could someone lend an explanation as to why the compiler will allow this situation to occur?

like image 503
Zach Avatar asked Jul 18 '11 16:07

Zach


2 Answers

You're confusing "handling" an exception with inheritance rules. When you implement or override a method, there is no rule that says the new method must throw exactly the same exceptions that the implemented/overridden method does. The only rule is that it cannot throw a checked exception that is outside the range of allowable exceptions for the parent method. Think of the interface as establishing a contract with the outside world. It says, "anybody who calls this method must be prepared to handle these types of exception". Implementors are then free to throw the exception, knowing that it will be handled, but they're by no means required to throw it.

like image 172
Ryan Stewart Avatar answered Oct 02 '22 19:10

Ryan Stewart


In addition to the previous answers, its worth to note that this code is perfectly ok for checked exceptions:

interface Translator {
    String translate(String s) throws IOException; /* <-- Checked exception */
}

class EnglishGermanTranslator implements Translator {
    @Override
    public String translate(String s) {  // <-- no exception, but its ok
        return ""; // logic is irrelevant...
    }
}

public class Test {
    public static void main(String[] args) {
        EnglishGermanTranslator t = new EnglishGermanTranslator();
        t.translate("Text to translate");  // No problems...
    }
}

But when we refer to the EnglishGermanTranslator via Translator, we have to catch an appropriate exception:

public class Test {
    public static void main(String[] args) {
        Translator t = new EnglishGermanTranslator();
        t.translate("Text to translate");  // <-- compilation error... try-catch required  (or throws in main)
    }
}
like image 41
guitar_freak Avatar answered Oct 02 '22 18:10

guitar_freak