¿Cómo se elige un método sobrecargado cuando un parámetro es el valor nulo literal?

Resuelto zakSyed asked hace 12 años • 8 respuestas

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);
   }
}

El resultado de este programa es "Versión de cadena". Pero no pude entender por qué al pasar un valor nulo a un método sobrecargado se eligió la versión de cadena. ¿Es nula 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"

zakSyed avatar Oct 23 '12 21:10 zakSyed
Aceptado

¿Es nula una variable de cadena que apunta a nada?

Una referencia nula se puede convertir en una expresión de cualquier tipo de clase. Entonces, en el caso de String, esto está bien:

String x = null;

La Stringsobrecarga 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:

La intuición informal es que un método es más específico que otro si cualquier invocación manejada por el primer método puede pasarse al otro sin un error de tipo en tiempo de compilación.

En su segundo caso, ambos métodos siguen siendo aplicables, pero ninguno Stringni StringBufferes más específico que el otro, por lo tanto ninguno de los métodos es más específico que el otro, de ahí el error del compilador.

Jon Skeet avatar Oct 23 '2012 14:10 Jon Skeet

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, 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. Más adelante dice:

La referencia nula siempre puede sufrir una conversión de referencia ampliada a cualquier tipo de referencia.

Por qué el compilador elige ampliarlo a String bien podría explicarse en la respuesta de Jon .

Edwin Dalorzo avatar Oct 23 '2012 14:10 Edwin Dalorzo