Dodałem trzy metody z parametrami:
public static void doSomething(Object obj) {
System.out.println("Object called");
}
public static void doSomething(char[] obj) {
System.out.println("Array called");
}
public static void doSomething(Integer obj) {
System.out.println("Integer called");
}
Kiedy dzwonię doSomething(null)
, kompilator zgłasza błąd jako niejednoznaczne metody . Więc jest problem, ponieważ Integer
i char[]
metody lub Integer
i Object
metody?
java
oop
null
overloading
Phani
źródło
źródło
Integer
sięint
.reference to doSomething is ambiguous
błędu.Odpowiedzi:
Java zawsze będzie próbowała użyć najbardziej konkretnej odpowiedniej wersji dostępnej metody (patrz JLS §15.12.2 ).
Object
,char[]
IInteger
wszystko może wziąćnull
jako ważnej wartości. Dlatego wszystkie 3 wersje mają zastosowanie, więc Java będzie musiała znaleźć najbardziej szczegółową.Ponieważ
Object
jest to nadtypchar[]
, wersja tablicowa jest bardziej szczegółowa niżObject
-wersja. Jeśli więc istnieją tylko te dwie metody,char[]
zostanie wybrana wersja.Gdy dostępne są obie wersje
char[]
iInteger
, obie są bardziej szczegółowe,Object
ale żadna nie jest bardziej szczegółowa niż druga, więc Java nie może zdecydować, którą z nich wywołać. W takim przypadku musisz wyraźnie wspomnieć, który z nich chcesz wywołać, rzutując argument na odpowiedni typ.Należy zauważyć, że w praktyce problem ten występuje znacznie rzadziej, niż mogłoby się wydawać. Powodem tego jest to, że dzieje się tak tylko wtedy, gdy jawnie wywołujesz metodę z
null
lub ze zmienną raczej niespecyficznego typu (na przykładObject
).Wręcz przeciwnie, następujące wezwanie byłoby całkowicie jednoznaczne:
char[] x = null; doSomething(x);
Chociaż nadal przekazujesz wartość
null
, Java dokładnie wie, którą metodę wywołać, ponieważ weźmie pod uwagę typ zmiennej.źródło
Każda para tych trzech metod jest sama w sobie niejednoznaczna, gdy jest wywoływana z
null
argumentem. Ponieważ każdy typ parametru jest typem referencyjnym.Poniżej przedstawiono trzy sposoby wywołania jednej określonej metody z wartością null.
doSomething( (Object) null); doSomething( (Integer) null); doSomething( (char[]) null);
Czy mogę zasugerować usunięcie tej niejednoznaczności, jeśli faktycznie planujesz wywoływać te metody z
null
argumentami. Taki projekt zachęca do błędów w przyszłości.źródło
Integer
-char[]
para jest niejednoznaczna, ponieważ w pozostałych dwóch przypadkach kompilator Java może wybrać najbardziej konkretny wybór, jak opisano w @JoachimSauer.null
parametrem as. Pod tym warunkiem wszystkie trzy pary są niejednoznaczne. W ogólnym przypadku zgadzam się, że tylkoInteger - char[]
para jest niejednoznaczna.doSomething(null)
napublic static void doSomething(String str) { System.out.println("String called"); }
To zwróci ciąg o nazwie.null
jest prawidłową wartością dla dowolnego z trzech typów; więc kompilator nie może zdecydować, której funkcji użyć. Użyj czegoś takiego jakdoSomething((Object)null)
lubdoSomething((Integer)null)
zamiast.źródło
Każda klasa w Javie rozszerza klasę Object, nawet klasa Integer rozszerza również Object. Dlatego zarówno Object, jak i Integer są uważane za instancję Object. Więc kiedy jako parametr przekażesz null, kompilator nie będzie wiedział, którą metodę obiektu wywołać, tj. Z parametrem Obiekt lub parametr Integer, ponieważ oba są obiektami, a ich odniesienie może mieć wartość null. Ale prymitywy w Javie nie rozszerzają Object.
źródło
Próbowałem tego i kiedy istnieje dokładnie jedna para przeciążonych metod, a jedna z nich ma parametr typu Object, wówczas kompilator zawsze wybierze metodę z bardziej konkretnym typem. Ale jeśli istnieje więcej niż jeden określony typ, kompilator zgłasza niejednoznaczny błąd metody.
Ponieważ jest to zdarzenie czasu kompilacji, może się to zdarzyć tylko wtedy, gdy celowo przekaże wartość null do tej metody. Jeśli jest to zrobione celowo, lepiej jest ponownie przeciążać tę metodę bez parametrów lub w ogóle utworzyć inną metodę.
źródło
występuje niejednoznaczność z powodu funkcji doSomething (char [] obj) i doSomething (Integer obj).
char [] i Integer są takie same nadrzędne dla null, dlatego są niejednoznaczne.
źródło
class Sample{ public static void main (String[] args) { Sample s = new Sample(); s.printVal(null); } public static void printVal(Object i){ System.out.println("obj called "+i); } public static void printVal(Integer i){ System.out.println("Int called "+i); } }
Wynik to Int o nazwie null, a więc niejednoznaczność występuje w przypadku char [] i Integer
źródło