fani
He añadido tres métodos con parámetros:
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");
}
cuando estoy llamando doSomething(null)
entonces el compilador arroja un error como métodos ambiguos. Así es el problema porque Integer
y char[]
métodos o Integer
y Object
¿métodos?
Joaquín Sauer
Java siempre intentará usar la versión aplicable más específica de un método que esté disponible (ver JLS §15.12.2).
Object
, char[]
y Integer
todos pueden tomar null
como un valor válido. Por lo tanto, las 3 versiones son aplicables, por lo que Java tendrá que encontrar la más específica.
Ya que Object
es el supertipo de char[]
la versión de la matriz es más específica que la Object
-versión. Entonces, si solo existen esos dos métodos, el char[]
se elegirá la versión.
Cuando tanto el char[]
y Integer
hay versiones disponibles, entonces ambas cosas de ellos son más específicos que Object
pero ninguno es más específico que el otro, por lo que Java no puede decidir a cuál llamar. En este caso, deberá mencionar explícitamente a cuál desea llamar emitiendo el argumento al tipo apropiado.
Tenga en cuenta que, en la práctica, este problema ocurre con mucha menos frecuencia de lo que uno podría pensar. La razón de esto es que solo sucede cuando estás llamando explícitamente a un método con null
o con una variable de un tipo poco específico (como Object
).
Por el contrario, la siguiente invocación sería perfectamente inequívoca:
char[] x = null;
doSomething(x);
Aunque sigues pasando el valor null
Java sabe exactamente qué método llamar, ya que tendrá en cuenta el tipo de variable.
-
Esto se indica para Java 7. ¿Eso también se aplica a las versiones anteriores de Java? Quiero decir: si tiene varias firmas de métodos con parámetros solo a lo largo de una jerarquía de tipos, ¿entonces está en el lado de guardar con nulo como valor real? Y si ha creado una “jerarquía para” como en el ejemplo aquí, ¿entonces no lo es?
– Christian Gosh
13 de febrero de 2015 a las 12:29
-
Estoy bastante seguro de que esas reglas son las mismas para al menos todo desde Java 1.1 (excepto por la adición de genéricos, obviamente).
– Joaquín Sauer
13 de febrero de 2015 a las 15:04
-
¿Significa esto que si el compilador tuviera que elegir entre doSomething(String str) y doSomething(Object obj) durante el tiempo de ejecución con doSomething(null), se llamará a doSomething(String str).
– Sameer
10 de noviembre de 2016 a las 9:22
jmg
Cada par de estos tres métodos es ambiguo por sí mismo cuando se llama con un null
argumento. Porque cada tipo de parámetro es un tipo de referencia.
Las siguientes son las tres formas de llamar a uno de sus métodos específicos con nulo.
doSomething( (Object) null);
doSomething( (Integer) null);
doSomething( (char[]) null);
¿Puedo sugerir eliminar esta ambigüedad si realmente planea llamar a estos métodos con null
argumentos Tal diseño invita a errores en el futuro.
-
Solamente
Integer
–char[]
pair es ambiguo, porque en otros dos casos, el compilador de Java puede elegir la opción más específica, como describió @JoachimSauer.– kajacx
11 de agosto de 2015 a las 6:54
-
@kajacx: la pregunta original de OP era llamar a estos métodos con
null
como parámetro. Bajo esa condición previa, los tres pares son ambiguos. Para el caso general, estoy de acuerdo en que soloInteger - char[]
el par es ambiguo.– jmg
15 de septiembre de 2015 a las 5:51
-
qué pasa
doSomething(null)
porpublic static void doSomething(String str) { System.out.println("String called"); }
Esto devolverá la cadena llamada.– Sameer
7 de noviembre de 2016 a las 15:13
-
¿Es posible usar una anotación como “anulable” o “no anulable” y configurar las declaraciones para que solo el método con el que desea obtener un nulo de modo que un argumento explícito “nulo” (pero de tipo nulo implícito) siempre seleccione sin ambigüedades? una sobrecarga especifica??
– peterk
18 de julio de 2017 a las 21:43
null
es un valor válido para cualquiera de los tres tipos; por lo que el compilador no puede decidir qué función usar. Usa algo como doSomething((Object)null)
o doSomething((Integer)null)
en cambio.
-
Eliminé el método con el parámetro Integer, está invocando la función y devolviendo la salida como “Matriz llamada”entonces, ¿cuál es el contrato entre matriz y objeto?
– Fani
8 de marzo de 2011 a las 8:01
-
Las matrices de Java también son objetos.
– Zds
8 de marzo de 2011 a las 8:53
Cada clase en Java extiende la clase Object. Incluso la clase Integer también extiende Object. Por lo tanto, tanto Object como Integer se consideran instancias de Object. Entonces, cuando pasa nulo como parámetro, el compilador se confunde sobre qué método de objeto llamar, es decir, con el parámetro Objeto o el parámetro Integer, ya que ambos son objetos y su referencia puede ser nula. Pero las primitivas en Java no extienden Object.
Jafar Alí
He intentado esto y cuando hay exactamente un par de métodos sobrecargados y uno de ellos tiene un objeto de tipo de parámetro, el compilador siempre seleccionará el método con un tipo más específico. Pero cuando hay más de un tipo específico, el compilador arroja un error de método ambiguo.
Dado que este es un evento de tiempo de compilación, esto solo puede suceder cuando uno intencionalmente pasa nulo a este método. Si esto se hace intencionalmente, es mejor sobrecargar este método nuevamente sin parámetros o crear otro método por completo.
nagarjuna chimakurthi
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 salida se llama Int nula y, por lo tanto, la ambigüedad es con char[] y entero
doctor mido
Hay una ambigüedad debido a doSomething(char[] obj)
y doSomething(Integer obj)
.
carbonizarse[] y Integer ambos son iguales superiores para nulo, por eso son ambiguos.
Solo cambia el
Integer
aint
.– Mudassir
8 de marzo de 2011 a las 7:59
@Mudassir: ¿y qué resolvería eso exactamente?
– Joaquín Sauer
8 de marzo de 2011 a las 8:02
@Joachim Sauer: si se cambia de Integer a int, entonces nulo no se refiere a tipos primitivos en Java, por lo que el compilador no arrojará un error.
– Fani
8 de marzo de 2011 a las 8:05
@Joachim Sauer: No arrojará la
reference to doSomething is ambiguous
error.– Mudassir
8 de marzo de 2011 a las 8:09