2015-10-07 6 views
5

Почему выбрасывается методом части его подписи. Кажется странным включать это. Вот пример, где он находится на пути.Почему выбрасывается часть метода подписи

@Overide 
public void foo() { 
    throw new UnsupportedOperationException(); 
} 

Если кто-нибудь видит этот метод снаружи, он может попытаться его использовать, не зная, что он не поддерживается. Они будут изучать его только при попытке запустить код.

Однако, если они могут сделать что-то подобное, они будут знать, глядя на метод, который не поддерживается, и если UnsupportedOperationException не расширяет RuntimeException, они получат ошибку компиляции. EDIT1: Но это невозможно, потому что броски являются частью сигнатуры, поэтому переопределение не будет работать.

@Overide 
public void foo() throws UnsupportedOperationException { 
    throw new UnsupportedOperationException(); 
} 

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

+3

Вы, кажется, отвечаете на свой собственный вопрос здесь? Это на подпись, потому что теперь вы (и компилятор) знаете, что код будет генерировать исключение и что его нужно обрабатывать? – Erik

+3

Непроверенные исключения и условия, когда они выбрасываются, должны быть задокументированы в javadoc. Эта парадигма используется во встроенных библиотеках Java и предлагается несколькими книгами, например. Эффективная Java, чтобы назвать ее. Объявление их в подписи, как вы правильно отметили, не требуется компилятором. – Danstahr

+0

Что вы спрашиваете, нужно ли выкинуть исключенное исключение или нет. Для запуска вашего метода используется '@ Override', который указывает, что он должен следовать контракту (аннотация или интерфейс), но для исключенных исключений вы не обязаны это делать. Независимо от того, выбрали ли вы его бросить или не всегда придерживаетесь хорошей оценки, как упомянуто @danstahr, добавьте его на javadoc. –

ответ

4

Часть throws не указывает на то, что этот метод необходим для выброса упомянутого исключения (-ов), даже при определенных значениях. Это говорит только о том, что функции разрешено делать это.

В том числе throws UnsupportedOperationException, следовательно, не означает, что метод не поддерживается. Кроме того, UnsupportedOperationException является RuntimeException, поэтому способ может быть throw, который в любом случае.

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

Это означает, например, что переопределение метода означает, что вы не можете добавлять исключения, которые могут быть выбраны, в противном случае вы нарушите возможность проверки того, что метод, вызывающий этот метод, не может выбросить ничего, кроме указанного , Другой способ был бы возможен (но я не уверен, поддерживает ли Java это), переопределяя метод, который может бросать тот, который не может выбраться.

Так, например:

class B { 
    int fubar(int) throws ExceptionA { 
    } 

    int frob(int) throws ExceptionA { 
     return fubar(int); 
    } 
} 

class D extends B { 
    int fubar(int) throws ExceptionB { 
    } 
} 

Теперь frob указано в возможно throw только ExceptionA, но в призыве this.fubar это откроет возможность того, что что-то другое выкинули, но fubar определяется возможно только throwExceptionA. Вот почему D.fubar является недопустимым переопределением, так как это откроет возможность того, что this.fubar действительно выбрасывает ExceptionB, и компилятор не сможет гарантировать, что frob не выбрасывает ExceptionB.

2

Java имеет два различных типа исключений: checked Исключения и unchecked исключений.

Непроверенные исключения являются подклассами RuntimeException, и вам не нужно добавлять объявление бросков.Все остальные исключения должны обрабатываться в теле метода либо с помощью инструкции try/catch, либо с помощью объявления throws.

Пример для исключенных исключений: IllegalArgumentException, который иногда используется для уведомления о том, что метод был вызван с незаконными аргументами. Никаких бросков не требуется.

Пример проверенных исключений: IOException, что некоторые методы из пакета java.io могут выбрасывать. Либо используйте try/catch или add throw IOException для объявления метода и делегируйте обработку исключений вызывающему методу.