2013-02-09 32 views
13

Mam następujący fragment kodu:Dziwne zachowanie Java zerowy w Metodzie Przeciążenie

public static void foo(Object x) { 
    System.out.println("Obj"); 
} 
public static void foo(String x) { 
    System.out.println("Str"); 
} 

Jeśli zadzwonię foo(null) dlaczego nie ma dwuznaczności? Dlaczego program nazywa się foo(String x) zamiast foo(Object x)?

+2

Czy przeciążenia nie zostały statycznie rozwiązane przy użyciu typu kompilacji wyrażenia? –

+0

'foo (null)' nazywa metodę klasy wyższej –

+1

@GrijeshChauhan Jaka klasa wyższa. Pytanie nie wspomina o hierarchii klasowej. – millimoose

Odpowiedz

20

dlaczego program wywołuje foo(String x) zamiast foo(Object x)

To dlatego String klasa rozciąga się od Object i stąd jest bardziej charakterystyczne dla Object. Tak więc kompilator decyduje się na wywołanie tej metody. Pamiętaj, że kompilator zawsze wybiera najbardziej specyficzną metodę wywołania. Zobacz Section 15.12.5 of JLS

Jeśli więcej niż jedna metoda jest członkiem zarówno dostępne i stosowane do wywołania metody, konieczne jest, aby wybrać jedną z wytworzeniem deskryptor dla metody wysyłki run-time. 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.

Jednakże, jeśli masz dwie metody z parametrem - String i Integer, wtedy dostanie ambiguity błąd na null, jak kompilator nie może zdecydować, który z nich jest bardziej specyficzne, ponieważ są one non-kowariantna typy.

+0

+1, ale może użyć cytowania JLS – millimoose

+0

To 15.12.2 - zobacz również to pytanie http://stackoverflow.com/questions/5229809/method-overloading- for-null-parameter –

+0

jak mogę nazwać najmniej konkretną metodę? –

2

Po wybraniu dwóch metod, w których argument jest prawidłowy dla obu parametrów, kompilator zawsze wybierze najbardziej specyficzny parametr jako dopasowanie. W tym przypadku, null jest literałem, który może być traktowany jako Object i String. String jest bardziej szczegółowy i podklasę Object, więc kompilator go używa.

+0

Dzięki za odpowiedź – dreamcrash

5

To się nazywa metoda most specific.

Ponieważ String jest podklasą obiektu, ciąg jest "bardziej szczegółowy" niż obiekt.

5
  1. Typ null jest z definicji podtyp każdej innej odniesienia. Cytuj JLS 4.1:

    Referencja zerowa może zawsze zostać rozszerzona o konwersję odniesienia do dowolnego typu odniesienia.

  2. Rozdzielczość podpisu metody zaangażowanych w inwokacji następująco zasadę najbardziej konkretnego podpisu w zbiorze wszystkich kompatybilnych podpisów. (JLS 15.12.2.5 Wybór metody najbardziej szczegółowej).

Łącznie oznacza to, że w twoim przykładzie wybrano przeciążenie String.