J'ai ajouté trois méthodes avec des paramètres:
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");
}
Lorsque j'appelle doSomething(null)
, le compilateur renvoie l'erreur en tant que méthode ambiguë . Le problème vient-il donc des méthodes Integer
et char[]
ou des méthodes Integer
et Object
?
Java essayera toujours d'utiliser la version applicable la plus spécifique d'une méthode disponible (voir JLS §15.12.2 ).
Object
, char[]
et Integer
peuvent tous prendre null
comme valeur valide. Par conséquent, toutes les 3 versions sont applicables, Java devra donc trouver la plus spécifique.
Puisque Object
est le super-type de char[]
, la version du tableau est plus spécifique que la version Object
-. Donc, si seules ces deux méthodes existent, la version char[]
sera choisie.
Lorsque les versions char[]
et Integer
sont toutes deux disponibles, alors les deux sont plus spécifiques que Object
mais aucune n'est plus spécifique que l'autre. Java ne peut donc pas choisir celle à appeler. Dans ce cas, vous devrez indiquer explicitement celui que vous souhaitez appeler en définissant l'argument sur le type approprié.
Notez que dans la pratique, ce problème se produit beaucoup plus rarement qu'on pourrait le penser. La raison en est que cela ne se produit que lorsque vous appelez explicitement une méthode avec null
ou avec une variable d'un type plutôt non spécifique (tel que Object
).
Au contraire, l'invocation suivante serait parfaitement claire:
char[] x = null;
doSomething(x);
Bien que vous transmettiez toujours la valeur null
, Java sait exactement quelle méthode appeler, car il tiendra compte du type de la variable.
Chaque paire de ces trois méthodes est ambiguë lorsqu'elle est appelée avec un argument null
. Parce que chaque type de paramètre est un type de référence.
Voici trois méthodes pour appeler une de vos méthodes spécifiques avec null.
doSomething( (Object) null);
doSomething( (Integer) null);
doSomething( (char[]) null);
Puis-je suggérer de supprimer cette ambiguïté si vous envisagez d'appeler ces méthodes avec les arguments null
Une telle conception invite des erreurs dans le futur.
null
est une valeur valide pour l’un des trois types; le compilateur ne peut donc pas décider quelle fonction utiliser. Utilisez quelque chose comme doSomething((Object)null)
ou doSomething((Integer)null)
à la place.
Chaque classe en Java étend Object class.Even La classe Integer étend également Object. Par conséquent, Object et Integer sont considérés comme une instance d'objet. Ainsi, lorsque vous transmettez null en tant que paramètre, le compilateur confond la méthode d’objet à appeler, c.-à-d. Avec le paramètre Object ou le paramètre Integer, car ils sont tous deux objets et leur référence peut être null. Mais les primitives en Java n’étend pas Object.
J'ai essayé cela et lorsqu'il y a exactement une paire de méthode surchargée et que l'une d'entre elles a un type de paramètre Object, le compilateur sélectionnera toujours la méthode avec un type plus spécifique. Mais lorsqu'il existe plusieurs types spécifiques, le compilateur renvoie une erreur de méthode ambiguë.
Comme il s'agit d'un événement de compilation, cela ne peut se produire que si l'on passe intentionnellement la valeur null à cette méthode. Si cela est fait intentionnellement, il est préférable de surcharger cette méthode sans paramètre ou de créer une autre méthode.
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);
}
}
La sortie s'appelle Int appelée null et l'ambiguïté est donc avec char [] et Integer
il y a une ambiguïté à cause de doSomething (char [] obj) et doSomething (Integer obj).
char [] et Integer sont les mêmes supérieurs pour null c'est pourquoi ils sont ambigus.