Объявление интерфейса с непроверенными и проверенными исключениями - PullRequest
8 голосов
/ 18 июля 2011

Я искал потенциальный ответ на свой вопрос ниже и не нашел его.

Я понимаю разницу между проверенными и непроверенными исключениями, а также то, что программист может / должен делать с ними.Тем не менее, я не совсем понимаю, как компилятор интерпретирует непроверенные исключения, когда речь идет об интерфейсах.

Недавно я программировал интерфейс и реализацию, аналогичную следующей:

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!");
        }
    }
}

Вотгде я запуталсяСледующая реализация также скомпилирует:

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

Почему компилятору все равно, что я объявил метод как исключение в интерфейсе?Я понимаю, что непроверенные исключения являются исключениями времени выполнения и что программисту не нужно их обрабатывать, но я не понимаю, почему, когда я явно указываю в своем интерфейсе, что хочу обработать исключение, оно не заставляет меня его обрабатывать.

Может ли кто-нибудь дать объяснение, почему компилятор допустит такую ​​ситуацию?

Ответы [ 3 ]

10 голосов
/ 18 июля 2011

Вы путаете «обработку» исключения с правилами наследования. При реализации или переопределении метода не существует правила, в котором говорится, что новый метод должен выдавать точно такие же исключения, что и реализованный / переопределенный метод. Единственное правило состоит в том, что он не может генерировать проверенное исключение, которое находится вне диапазона допустимых исключений для родительского метода. Думайте об интерфейсе как об установлении контракта с внешним миром. Он говорит: «Любой, кто вызывает этот метод, должен быть готов обработать исключения такого типа». В этом случае разработчики могут свободно генерировать исключение, зная, что оно будет обработано, но отнюдь не требуется для его выброса.

6 голосов
/ 11 августа 2014

В дополнение к предыдущим ответам стоит отметить, что этот код отлично подходит для проверенных исключений:

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...
    }
}

Но когда мы ссылаемся на EnglishGermanTranslator через Translator, мы должны поймать соответствующее исключение:

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)
    }
}
4 голосов
/ 18 июля 2011

Объявление исключений времени выполнения в предложении throws предназначено только для информации (и javadoc), чтобы пользователи вашего класса / интерфейса знали, чего ожидать в данной ситуации.

Поскольку они выполняются, компилятор ничего не применяет к ним - ни перехват, ни объявление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...