2009-07-15 9 views
5

Mam problem ze zrozumieniem tego pytania i wyjaśnieniem odpowiedzi na pytanie testowe SCJP 1.6. Oto problem:Var-arg tablic obiektów vs. tablica obiektów - próba zrozumienia pytania testowego SCJP

class A { } 
class B extends A { } 
public class ComingThru { 
    static String s = "-"; 
    public static void main(String[] args) { 
     A[] aa = new A[2]; 
     B[] ba = new B[2]; 
     sifter(aa); 
     sifter(ba); 
     sifter(7); 
     System.out.println(s); 
    } 
    static void sifter(A[]... a2) { s += "1"; } 
    static void sifter(B[]... b1) { s += "2"; } 
    static void sifter(B[] b1) { s += "3"; } 
    static void sifter(Object o) { s += "4"; } 
} 

Jaki jest wynik? Odpowiedź brzmi -434, ale to, co mnie rzuca, to wyjaśnienie książki. To znacznie różni się od tego, jak koncepcja została wyjaśniona wcześniej w rozdziale.

„Na ogół obciążonych VAR argumentach Metody dobiera koniec. Należy pamiętać, że tablice są obiektami. Wreszcie, Int mogą być zapakowane do liczby całkowitej i «rozszerzony»do obiektu.”

Dzieląc to, czy ktoś może dokładniej zdefiniować to wyjaśnienie?

  1. Generalnie, przeciążone metody var-args są wybierane jako ostatnie.
  2. Tablice są obiektami (faktycznie to rozumiem, ale dlaczego jest to istotne dla tego pytania).
  3. Int może być zapakowany do liczby całkowitej, a następnie "poszerzony" do obiektu.

Dzięki!

Odpowiedz

6

Książka próbuje wyjaśnić, dlaczego pierwsze dwa przeciążenia nie są nigdy wybierane: ponieważ znacznik zmiennoprzecinkowy ... powoduje, że są używane tylko wtedy, gdy nie dojdzie do co drugiego możliwego przeciążenia. W tym przypadku tak się nie dzieje - dwa zdania zaczynające się od "Zapamiętaj" wyjaśniają DLACZEGO tak się nie dzieje, dlaczego inne możliwe przeciążenia występują w pierwszym i ostatnim przypadku (drugi przypadek i jego zgodność z trzecim przeciążeniem przesiewacza jest oczywista): tablica jest obiektem, a int może zostać podzielony na bok, a następnie rozszerzony na obiekt, więc czwarte przeciążenie pasuje do pierwszego i ostatniego wywołania przesiewacza.

+0

Dzięki za wspaniałe wyjaśnienie! –

+0

@ hal100001, zawsze chętnie pomożemy - gdy wszystkie odpowiedzi będą już dostępne, pamiętaj, aby wybrać najlepszą/najbardziej pomocną dla akceptacji (jak mówisz, funkcja msaeed jest również bardzo przydatna - mówimy zasadniczo o tych samych rzeczach , ale moja ekspresja jest bardziej potoczna, jego, bardziej uporządkowana). –

4
  1. Gdy próbuje określić, która metoda do wywołania, kompilator najpierw szuka non metody vararg (np sifter(Object)) przed rozważeniem vararg jeden (np sifter(A[]...)), gdy obie metody należą do tej samej klasy (more lub mniej).

  2. Ponieważ tablica jest Object, wzywanie sifter(aa) dopasuje sifter(Object), stąd nawet nie rozważa sifter(A[]...).

  3. Od Java 5, kompilator może "skrzynka" prymitywny, to konwersję wartości pierwotnych (np int) do odpowiadających im Object (np Integer). Tak więc dla sifter(6), kompilator konwertuje int 6 na Integer 6, a zatem będzie pasował do metody sifter(Object).

+0

Niesamowite wytłumaczenie. Dzięki!!! –