2013-06-07 12 views
5

Nowicjusz Java tutaj; Jestem znacznie bardziej komfortowe w C#. To powiedziawszy, następujące zagadki mnie. Piszę niektóre klasy przeciążone z różnymi sygnaturami parametrów w Javie. Jednak nie może wydawać się rozróżniać pomiędzy Obiektem i podwójnym. Jednak nie ma problemu z Object i Double. Czy ktoś może wyjaśnić, co się dzieje?Dlaczego Java nie może odróżnić obiektów od liczb?

public void item(Object a, Object b, String c, String d) {/*Stuff*/} 
public void item(double a, double b, String c, String d) {/*Stuff*/} 

public void UseIt(double a, double b, Double c, Double d) 
{ 
    item(a, b, someString, someOtherString); // Claims it's ambiguous 
} 

czy jest to tylko przypadek mojego idystemowego systemu rozwoju?

Przykro nam z przykładu; to jest jak te, które się nie powiodły (których tak naprawdę tu nie mogę tu podać) i popełniłem błąd, nie wypróbowując go przed wpisaniem go ...

+6

Twój kod faktycznie działa dla mnie. Właśnie skompilowałem tę klasę: public class Test { public void item (double a, double b, String c, String d) {/ * stuff * /} publiczny element typu void (obiekt a, obiekt b, ciąg c, ciąg d) {/ * Rzeczy * /} publiczny void UseIt (double a, double b, double c, Double d) { item (a, b, "", ""); // Twierdza, że ​​jest niejednoznaczny: } } –

+0

podajesz dwa podwójne argumenty w łańcuchu! –

+0

Argumenty b, c, d to po prostu czerwone śledzie. –

Odpowiedz

4

Dzieje się tak, ponieważ twoje IDE (wprowadzające w błąd, w tym przypadku) widzi możliwy autoboxing.

Na przykład, jeśli tworzysz List<Integer>, można dodać do niej int: Jest autoboxing z int do Integer. Unxobing jest odwrotny: Integer do int. Zauważ, że zarówno boksowanie, jak i rozpakowywanie mają zastosowanie tylko do liczbowych typów pierwotnych (ALE NOT to z nich).

Tutaj nie ulega wątpliwości, że metoda z double zostanie ostatecznie wybrana (ponieważ jest bardziej szczegółowa), ale IDE uważa, że ​​istnieje możliwa niejednoznaczność.

Przykład ten kod:

public final class Test 
{ 
    public static void item(Object a, Object b, String c, String d) 
    { 
     System.out.println("Object"); 
    } 

    public static void item(double a, double b, String c, String d) 
    { 
     System.out.println("double"); 
    } 

    public static void unbox(final double d) 
    { 
     System.out.println("Unboxed!"); 
    } 

    public static void useIt(double a, double b, Double c, Double d) 
    { 
     // primitives 
     item(a, b, "", ""); 
     // cast to corresponding classes 
     item((Double) a, (Double) b, "", ""); 
     // objects 
     item(c, d, "", ""); 
     // unboxed by the "unbox" method which takes a "double" as an argument 
     unbox(new Double(2.0)); 
    } 

    public static void main(final String... args) 
    { 
     // Autoboxing of the third and fourth argument 
     useIt(1.0, 1.0, 1.0, 1.0); 
    } 
} 

wyjścia:

double 
Object 
Object 
Unboxed! 

jednak pamiętać, że nie można nazwać:

useIt((Double) a, b, c, d); // No autoboxing of "b" 
+4

tak, ale jvm nie powinien boksować z powodu przeciążenia. Kod, który opublikował poprawnie, kompiluje się dla mnie, jeśli zastąpię someString i SomeOtherString "" –

+1

@ TrustNoOne tak, o tym też wspominałem. – fge

+0

Chciałbym wiedzieć, skąd się wzięły i dlaczego ... – fge

-2

Skoro masz dwie metody, które mają taką samą nazwę z 4 parametry, możliwe jest, że kompilator nie wie, do której metody się odwołujesz. Twoje połączenie nie daje jasnej definicji tego, do którego chcesz zadzwonić. Powinieneś zmienić nazwy jednej z metod przedmiotów lub dokładniej zdefiniować parametry.

+0

Przeciążanie metody samo w sobie jest w porządku z kompilatorem. Jest to niejednoznaczne wywołanie przeciążonej metody, która nie działa. –

+0

... zapomniałem dodać: ale to nie jest nawet niejednoznaczne i kompiluje. –

9

Ta klasa kompiluje dobrze (tylko przetestowane, aby mieć pewność, umieścić go w Test.java i skompilowany z linii poleceń)

public class Test { 
    public void item(double a, double b, String c, String d) {/*Stuff*/} 
    public void item(Object a, Object b, String c, String d) {/*Stuff*/} 
    public void UseIt(double a, double b, Double c, Double d) { 
     item(a, b, "", ""); // Claims it's ambiguous 
    } 
} 

Twój problem może być związany z faktem, że jesteś przechodzącej dwa dwuosobowe (c i d) jako trzeci i czwarty argument, zamiast dwóch ciągów.

+7

To jest jedyna słuszna odpowiedź, która jest trochę ironiczna - "Twój problem jest zły". –

+1

Nie mogłem uwierzyć, że przeciążanie pomiędzy typami wartości i typami pudełkowymi nie działało ... Musiałem tylko przetestować przed odpowiedzią: D To jest również powód, dla którego mam niski ryps: nie odpowiadam losowo mając nadzieję, że mam rację aby zdobyć punkty –

+0

OTOH, jeśli zmienisz obie metody na początek z 'Object', to nie działa. –

Powiązane problemy