"¡Hola, Amigo! Hace un par de días te hablé de los métodos de sobrecarga. ¿Entendiste todo?"

"Sí. Lo recuerdo. Cada método de clase debe ser único. Un método miembro es único si la clase no tiene otro método con el mismo nombre y tipos de parámetros (y el orden de los parámetros es importante)".

"¡Muy bien! Veo que has aprendido bien esa lección. Hoy quiero ampliar un poco tus conocimientos en este tema. ¿A qué método crees que se llamará en cada caso?"

Código
class Cat
{
 public static void print(int n)
 {
  System.out.println(n);
 }
 public static void print(short n)
 {
  System.out.println(n);
 }
 public static void print(Integer n)
 {
  System.out.println(n);
 }
 public static void print(String s)
 {
  System.out.println(s);
 }
public static void main(String[] args)
{
  Cat.print(1);
  Cat.print((byte)1);
  Cat.print("1");
  Cat.print(null);
 }
}

"Es difícil de decir."

"En el primer caso, 1 es un int . Tenemos una coincidencia del 100 % con el método que toma un int. Se llamará al primer void print(int n) .

En el segundo caso, no tenemos un método que tome un byte. Pero hay dos métodos que toman un short y un int. Según las reglas de ampliación de tipo, un byte primero se ampliará a un valor corto y luego se ampliará a un int. Por lo tanto, el veredicto es que la impresión vacía (n corta). sera llamado.

En el tercer caso, tenemos una coincidencia del 100% con el método que toma una Cadena. La impresión vacía (String s). se llamará al método.

El cuarto caso es ambiguo. null no tiene un tipo específico. El compilador se negará a compilar este código . En este caso, necesitamos escribir Cat.print((Integer)null) para llamar al tercer método y Cat.print((String)null) para llamar al cuarto".

"Eso fue muy informativo. Gracias".

"Me gustaría señalar que al determinar el método correcto para llamar, los tipos solo pueden ampliarse. No pueden reducirse. Considere este ejemplo:"

Código
class Cat
{
 public static void print(short n)
 {
  System.out.println(n);
 }
 public static void print(Integer n)
 {
  System.out.println(n);
 }

 public static void main(String[] args)
 {
  Cat.print((byte)1);
  Cat.print(1);
 }
}

En el primer caso, el tipo de byte se ampliará a corto y el primer método se llamará: void print(n corto). .

En el segundo caso, habrá una conversión de ampliación implícita de int a Integer, y luego se llamará al segundo método: void print(Integer n). .

"No me esperaba eso".

"No, aquí está la verdadera sorpresa:"

codigo Java Descripción
 class Cat
{
 public static void print(Object o)
 {
  System.out.println(o);
 }
 public static void print(String s)
 {
  System.out.println(s);
 }

 public static void main(String[] args)
 {
  Cat.print(1);
  Cat.print(null);
 }
}
En el primer caso, int se extenderá a Integer. Debido a que no existe un método para Integer, el método más adecuado (y el que se llama) es void print(Object o)

En el segundo caso, no habrá ningún error de compilación y se llamará a void print(String s) , lo cual no es algo obvio.

"Amigo, espero que entiendas que en tales casos es mejor especificar un operador de conversión de tipo (como hicimos con «(byte)») para saber exactamente qué método se llamará".

"Nunca esperé que surgieran problemas por sobrecargar los métodos. Pero luego llegas tú. Gracias, Rishi. Mantendré la guardia en este punto".