2014-12-19 16 views
6

Rozważmy następujący InterfaceDlaczego wywołujący metodę, która zgłasza wyjątek, nie musi obsługiwać wyjątku w tej sytuacji?

package hf; 

public interface BadInterface 
{ 
    void meth() throws Exception; 
} 

, który jest realizowany w następujących klas:

package hf; 

public class apples implements BadInterface 
{ 
    public static void main(String[] args) 
    { 
     new apples().meth(); 
    } 

    public void meth() 
    { 
     System.out.println("Ding dong meth."); 
    } 
} 

Chociaż met() to metoda zgłasza wyjątek, rozmówcę metodzie met() jest nie musi obsługiwać ani deklarować wyjątku, a mimo to program działa poprawnie. Dlaczego tak jest? Czy nie narusza zasady, że za każdym razem, gdy wywołujesz metodę, która zgłasza wyjątek, musisz wychwycić wyjątek lub zadeklarować, że sam rzucisz wyjątek?

+0

Powinieneś zmienić nazwę swojej klasy na 'Jabłka' zgodnie z normami kodowania Java. –

Odpowiedz

7

Po zaimplementowaniu metody interfejsu można zadeklarować, że wyrzuciłeś mniejszej liczby wyjątków od niż podano w interfejsie.

Po wywołaniu new apples().meth() wywołujesz meth() w instancji apples. Kompilator wie, że nic nie wyrzuca, więc wszystko jest w porządku.

Gdybyś zrobić:

BadInterface foo = new apples(); // Note: should be Apples (code style) 
foo.meth(); 

wtedy trzeba by złapać wyjątek zadeklarowane w interfejsie, bo tylko kompilator wie, że ma do czynienia z instancji BadInterface.

+0

Należy również zauważyć, że wyjątki nie są częścią sygnatury metody. Dlatego możesz wdrożyć tę metodę bez dodawania do niej 'throws Exception'. Możesz również dodać Wyjątki: 'public void meth() wyrzuca IOException, FooException' – Davio

+1

@Davio Wyjątki są z pewnością istotne w podpisie - nie można na przykład rzucić żadnych sprawdzonych wyjątków, które nie są wymienione w interfejsie. –

+1

Ostatnim, bardziej pasującym terminem jest "kształt", odpowiedni do konwersji lambda. Deklarowane wyjątki zdecydowanie przyczyniają się do kształtu metody. –

0

Według JLS Requirements in Overriding and Hiding:

B klasy lub interfejsu, a A jest nadrzędna lub superinterface B, a m2 deklaracja metoda zadajnikami B lub ukrywa oświadczenie Metoda M1 w A. Następnie :

Dla każdego sprawdzane typ wyjątku wymienione w rzutach klauzuli m2 że sama klasa wyjątku lub jedną z jego supertypes musi występować w usunięciu (§4.6) z rzutów klauzuli M1; w przeciwnym razie wystąpi błąd kompilacji .

Oznacza, że ​​metoda rozszerzająca może mieć tylko silniejszą politykę wyjątków. Jeśli ma słabsze ograniczenia, wówczas metoda taka nie może być stosowana zamiast metody bazowej i łamie koncepcję nadpisywania.

Powiązane problemy