Extraño comportamiento nulo de Java en Sobrecarga de método

Tengo el siguiente fragmento de código:

public static void foo(Object x) { System.out.println("Obj"); } public static void foo(String x) { System.out.println("Str"); } 

Si llamo a foo(null) ¿por qué no hay ambigüedad? ¿Por qué el progtwig llama a foo(String x) lugar de foo(Object x) ?

por qué el progtwig llama a foo(String x) lugar de foo(Object x)

Esto se debe a que String clase String extiende desde Object y, por lo tanto, es más específica para Object . Entonces, el comstackdor decide invocar ese método. Recuerde, el comstackdor siempre elige el método más específico para invocar. Ver la Sección 15.12.5 de JLS

Si más de un método de miembro es accesible y aplicable a una invocación de 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 progtwigción Java usa la regla de que se elige el método más específico.

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 podría pasarse a la otra sin un error de tipo de tiempo de comstackción.

Sin embargo, si tiene dos métodos con el parámetro – String e Integer , entonces obtendrá un error de ambiguity para null , ya que el comstackdor no puede decidir cuál es más específico, ya que son tipos no covariantes.

Está llamando al método más específico .

Dado que String es una subclase de Object, String es “más específico” que Object.

  1. El tipo de null es, por definición, un subtipo de cualquier otro tipo de referencia . Citar JLS 4.1:

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

  2. La resolución de la firma del método implicada en una invocación sigue el principio de la firma más específica en el conjunto de todas las firmas compatibles. (JLS 15.12.2.5. Elegir el método más específico).

Tomados en conjunto esto significa que la sobrecarga String se elige en su ejemplo.

Cuando se le da una opción entre dos métodos donde el argumento es válido para ambos parámetros, el comstackdor siempre elegirá el parámetro más específico como una coincidencia. En este caso, null es un literal que puede manejarse como un Object y una String . String es más específico y una subclase de Object para que el comstackdor lo use.