2015-02-12 24 views
24
public class TestMain { 

    public static void methodTest(Exception e) { 
     System.out.println("Exception method called"); 
    } 

    public static void methodTest(Object e) { 
     System.out.println("Object method called"); 
    } 

    public static void methodTest(NullPointerException e) { 
     System.out.println("NullPointerException method called"); 
    } 

    public static void main(String args[]) { 
     methodTest(null); 
    } 
} 

wyjściowa: metoda NullPointerException nazywaWiele przeciążonych metod: Czy wartość pusta równa się wyjątkowi NullPointerException?

+6

Co się stanie, jeśli użyjesz 'methodTest ((Object) null);'? lub 'methodTest ((wyjątek) null);'? – MadProgrammer

+1

, jeśli użyto metody methodTest ((Object) null), wówczas wynikiem jest "Metoda obiektu nazwana". , jeśli użyto metody methodTest ((wyjątek)), wówczas wynikiem jest "Wyjątek". –

+0

Tak więc 'null' nie jest' NullPointerException', dlaczego kompilator decyduje się wywołać tę metodę, gdy wywołanie jest niejednoznaczne, nie wiem. – MadProgrammer

Odpowiedz

38

Jeśli istnieje kilka przeciążone metody, które mogą być wezwane z danego parametru (null w Twoim przypadku) kompilator wybiera najbardziej konkretny jeden.

Zobacz http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.5

W twoim przypadku methodTest(Exception e) jest bardziej szczegółowy niż methodTest(Object e), ponieważ wyjątek jest podklasą Object. A methodTest(NullPointerException e) jest jeszcze bardziej specyficzny.

Po zastąpieniu wyjątku NullPointerException inną podklasą wyjątku, kompilator wybierze ten.

Z drugiej strony, jeśli utworzysz dodatkową metodę, taką jak testMethod(IllegalArgumentException e), kompilator wygeneruje błąd, ponieważ nie wie, który z nich wybrać.

+0

Niepoprawny, gdy użyty zostanie 'IllegalArgumentException', wywoła metodę' methodTest (Exception e) '. – Runcorn

+2

@Runcorn Czy rzeczywiście tego spróbowałeś? Działa tak, jak opisano w mojej odpowiedzi tutaj. –

+0

Program Compender zgłasza błąd, jeśli system Windows static static void methodTest (NullPointerException e) { \t \t System.out.println ("Metoda NullPointerException nazywana"); \t} \t public static void methodTest (ArrayIndexOutOfBoundsException e) { \t \t System.out.println ("metoda ArrayIndexOutOfBoundsException zwany"); \t} \t są obecne i odciski "metoda ArrayIndexOutOfBoundsException zwany", jeśli tylko publiczne void methodTest (ArrayIndexOutOfBoundsException e) { \t \t System.out.println ("metoda ArrayIndexOutOfBoundsException zwany"); \t} \t jest obecny –

9

Kompilator postara się dopasować do najbardziej konkretnego parametru, który w tym przypadku jest NullPointerException. Można zobaczyć więcej informacji w Java Language Specification, sekcję 15.12.2.5. Choosing the Most Specific Method :

Jeśli więcej niż jedna metoda członkiem jest zarówno dostępne i stosowane do wywołania metody, konieczne jest, aby wybrać jedną z nich dostarczają deskryptor wyś wietlanie metody w czasie wykonywania. Język programowania Java wykorzystuje regułę, że wybrana jest najbardziej szczegółowa metoda.

Nieformalną intuicją jest to, że jedna metoda jest bardziej szczegółowa niż inna, jeśli jakakolwiek inwokacja obsługiwana przez pierwszą metodę może zostać przekazana do drugiej bez błędu typu kompilacji.

[...]

+0

W [Java Puzzlers] (http://www.javapuzzlers.com/) autorstwa Joshua Blocha i Neala Gaftera znajduje się zagadka poświęcona temu "najbardziej specyficznemu działaniu". – Timmos