2016-08-29 2 views
3

Я использую Java 7 и наткнулся на что-то очень интересное. Расширяя интерфейс java.lang.Appendable с помощью моего собственного интерфейса, я больше всего переопределяю каждый метод для целей документации.Удаление исключенного Java исключения при переопределении метода интерфейса?

Все три метода, определенные в java.lang.Appendable throws IOException, которые, как я думал, также должны были бы объявить мои переопределяющие методы. Тем не менее, я закончил удаление предложения throws на одном из переопределенных методов и, как ни странно, компилятор Java 7 не жаловался на недостающее объявление. Поэтому я пошел вперед и удалил предложение throws из двух других методов и снова, никаких жалоб от компилятора.

Итак, почему я могу переопределить метод в интерфейсе и удалить его предложение throws? И когда это явление стало законным на Java?

+0

Почему бы ему не быть законным? Почему вы должны ошибочно объявлять, что ваш метод генерирует исключение, которое, как вы знаете, это не так? – shmosel

+0

Я думал, если кто-нибудь скажет Appendable a = new MyInterfaceImpl(); что когда они сказали a.append («Foo»); их код все равно должен был бы попробовать IOException (что они будут). Но я предполагаю, что имеет смысл, что если MyInterface не бросает IOException для метода Appendable, тогда это нормально, потому что реализация MyInterface никогда не будет бросать IOException. Я был просто удивлен, увидев, что эта работа - все. Спасибо за понимание! –

ответ

3

Родительский интерфейс объявляет, что метод может выдать исключение. Реализация, которая не генерирует исключение, соответствует тому, которое может. В вашем интерфейсе объявляется, что реализации на самом деле не исключают исключения, но при этом соблюдают контракт родительского интерфейса.

Код, который присваивает ваши экземпляры переменной Appendable, должен поймать исключение, как определено, тогда как код, который обрабатывает ваши экземпляры, как ваш дочерний интерфейс, не потребуется.

Проще говоря:

interface Foo { 
    void m() throws Exception; 
} 

interface Bar extends Foo { 
    @Override 
    void m(); 
} 

void test(Foo foo, Bar bar) { 
    foo.m(); // must catch exception 
    bar.m(); // no exception declared to be thrown, so don't need to catch 
} 

Заметим также, что это тип переменной, а не объект, это важно:

Foo foo = new BarImpl(); 
foo.m(); // must catch exception 
+0

Удивительно, это имеет смысл. Благодаря! –

Смежные вопросы