Como se mencionó antes, la resolución de sobrecarga se realiza en tiempo de compilación.
Java Puzzlers tiene un buen ejemplo de ello:
Puzzle 46: El caso del Constructor confuso
Este puzzle se presenta con dos constructores confuso. El método principal invoca un constructor, pero ¿cuál? La salida del programa depende de la respuesta. ¿Qué imprime el programa, o es incluso legal?
public class Confusing {
private Confusing(Object o) {
System.out.println("Object");
}
private Confusing(double[] dArray) {
System.out.println("double array");
}
public static void main(String[] args) {
new Confusing(null);
}
}
Solución 46: Caso del Constructor confuso
... proceso de resolución de sobrecarga de Java funciona en dos fases. La primera fase selecciona todos los métodos o constructores que son accesibles y aplicables. La segunda fase selecciona el más específico de los métodos o constructores seleccionados en la primera fase. Un método o constructor es menos específico que otro si puede aceptar cualquier parámetro pasado al otro [JLS 15.12.2.5].
En nuestro programa, ambos constructores son accesibles y aplicables. El constructor Confusing (Objeto) acepta cualquier parámetro pasado a Confusing (double []), de modo Confusing (Objeto) es menos específica. (Cada doble matriz es un Objeto, pero no todas Objeto es una doble matriz.) Por consiguiente, el constructor más específico es Confusing (double []), lo que explica la salida del programa.
Este comportamiento tiene sentido si pasa un valor de tipo double []; es contra-intuitivo si pasa nulo. La clave para entender este rompecabezas es que la prueba para la que el método o el constructor es más específico no usa los parámetros reales: los parámetros que aparecen en la invocación. Se usan solo para determinar qué sobrecargas son aplicables. Una vez que el compilador determina qué sobrecargas son aplicables y accesibles, selecciona la sobrecarga más específica, utilizando solo los parámetros formales: los parámetros que aparecen en la declaración.
para invocar el Confusing (Objeto) constructor con un parámetro nulo , escribir nuevo Confusing ((Object) null). Esto asegura que solo Confusing (Object) es aplicable.Más en general, para obligar al compilador a seleccionar una sobrecarga específica, eche parámetros reales a los tipos declarados de los parámetros formales.
¿Puede explicar las especificaciones que citó por favor? Las dos oraciones parecen contradecirse entre sí. El ejemplo anterior usa métodos de instancia, sin embargo, el método invocado claramente no se está determinando en tiempo de ejecución. –
@Alex Worden: el tipo de tiempo de compilación ** de los parámetros del método ** se usa para determinar la firma del método a llamar, en este caso 'foo (Object)'. En tiempo de ejecución, la clase del ** objeto al que se llama el método ** determina qué implementación de ese método se llama, teniendo en cuenta que puede ser una instancia de una subclase del tipo declarado que anula el método. –