Me encontré con esta pregunta en un cuestionario,
public class MoneyCalc {
public void method(Object o) {
System.out.println("Object Verion");
}
public void method(String s) {
System.out.println("String Version");
}
public static void main(String args[]) {
MoneyCalc question = new MoneyCalc();
question.method(null);
}
}
La salida de este programa es "Versión de cadena". Pero no pude entender por qué pasar un nulo a un método sobrecargado eligió la versión de cadena. ¿Es null una variable de cadena que apunta a nada?
Sin embargo, cuando se cambia el código a,
public class MoneyCalc {
public void method(StringBuffer sb) {
System.out.println("StringBuffer Verion");
}
public void method(String s) {
System.out.println("String Version");
}
public static void main(String args[]) {
MoneyCalc question = new MoneyCalc();
question.method(null);
}
}
da un error de compilación que dice "El método método (StringBuffer) es ambiguo para el tipo MoneyCalc"
java
overloading
zakSyed
fuente
fuente
Respuestas:
Una referencia nula se puede convertir en una expresión de cualquier tipo de clase. Entonces, en el caso de
String
, esto está bien:La
String
sobrecarga aquí se elige porque el compilador de Java elige la sobrecarga más específica , según la sección 15.12.2.5 de JLS . En particular:En su segundo caso, ambos métodos son todavía aplicables, pero tampoco
String
niStringBuffer
es más específico que el otro, por lo tanto, ninguno de los métodos es más específico que el otro, por lo tanto el error, compilador.fuente
Object
puede tomar cualquier tipo y envolverlo en unObject
, mientras que aString
solo puede tomar unString
. En este caso,String
es más específico de un tipo en comparación con elObject
tipo.question.method((String)null)
)Además, JLS 3.10.7 también declara que "nulo" es un valor literal del "tipo nulo". Por tanto, existe un tipo llamado "nulo".
Más tarde, el JLS 4.1 establece que existe un tipo nulo del cual es imposible declarar variables, pero puede usarlo solo a través del literal nulo. Luego dice:
Por qué el compilador elige ampliarlo a String bien podría explicarse en la respuesta de Jon .
fuente
Puede asignar un
string
a unnull
valor para que sea válido y el orden de java y la mayoría de los lenguajes de programación se ajuste al tipo más cercano y luego al objeto.fuente
Para responder a la pregunta del título:
null
no es ni unString
ni unObject
, pero se puede asignar una referencia a cualquiera de los dosnull
.De hecho, me sorprende que este código incluso se compile. Intenté algo similar anteriormente y obtuve un error del compilador que decía que la llamada era ambigua.
Sin embargo, en este caso, parece que el compilador está eligiendo el método más bajo en la cadena alimentaria. Se supone que desea la versión menos genérica del método para poder ayudarlo.
Tendré que ver si puedo desenterrar el ejemplo en el que obtuve un error del compilador en este (aparentemente) exactamente el mismo escenario, aunque ...]
EDITAR: Ya veo. En la versión que hice, tenía dos métodos sobrecargados que aceptaban un
String
y unInteger
. En este escenario, no hay un parámetro "más específico" (como enObject
yString
), por lo que no puede elegir entre ellos, a diferencia de su código.¡Muy buena pregunta!
fuente
Dado que el tipo de cadena es más específico que el tipo de objeto. Digamos que agrega un método más que toma un tipo Integer.
Entonces obtendrá un error del compilador que dice que la llamada es ambigua. Como ahora tenemos dos métodos igualmente específicos con la misma precedencia.
fuente
El compilador Java proporciona la mayoría de tipos de clases derivadas para asignar nulos.
Aquí está el ejemplo para entenderlo:
salida: Clase B.
por otra parte:
Resultado: el método fun (C) es ambiguo para el tipo MyTest
Espero que ayude a comprender mejor este caso.
fuente
Fuente: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5
Concepto: método más específico
Explicación: si más de un método miembro es accesible y aplicable a la invocación de un método, es necesario elegir uno para proporcionar el descriptor para el envío del método en tiempo de ejecución. El lenguaje de programación Java utiliza la regla de que se elige el método más específico. Intente convertir el nulo en un tipo específico y el método que desee se llamará automáticamente.
fuente
Yo diría que no. NULL es un estado, no un valor. Consulte este enlace para obtener más información sobre esto (el artículo se aplica a SQL, pero creo que también ayuda con su pregunta).
fuente
null
es definitivamente un valor, como se define en la JLS.