0Pricing
Java Academy · Lección

Reglas de sobrecarga de métodos

Comprenda cómo Java resuelve los métodos sobrecargados y cuáles son los problemas habituales de ambigüedad.

Reglas de sobrecarga de métodos es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.

Reglas de la sobrecarga de métodos

La sobrecarga de métodos permite definir varios métodos con el mismo nombre, pero con listas de parámetros diferentes. Java selecciona la coincidencia más adecuada en tiempo de compilación mediante reglas de resolución precisas.

¿Qué es la sobrecarga?

Los métodos sobrecargados comparten un nombre, pero se diferencian en la cantidad, el tipo o el orden de sus parámetros. El tipo de retorno por sí solo NO basta para sobrecargar un método.

class Calculator {
    int add(int a, int b)     { return a + b; }
    double add(double a, double b) { return a + b; }
    int add(int a, int b, int c)   { return a + b + c; }

    // compile error — same signature, different return type only:
    // long add(int a, int b) { return a + b; }
}

Calculator calc = new Calculator();
System.out.println(calc.add(1, 2));       // 3 (int)
System.out.println(calc.add(1.5, 2.5));   // 4.0 (double)
System.out.println(calc.add(1, 2, 3));    // 6 (3-arg)

Resolución: la coincidencia más específica

Java elige el método aplicable más específico. La ampliación de tipos, el autoboxing y los varargs se prueban en ese orden de preferencia.

static void print(int x)    { System.out.println("int: "    + x); }
static void print(long x)   { System.out.println("long: "   + x); }
static void print(Object x) { System.out.println("Object: " + x); }

print(42);       // int: 42 (exact match — most specific)
print(42L);      // long: 42 (exact match)
print(3.14);     // Object: 3.14 (no float match, widening then autoboxing)

Ampliación antes que autoboxing

Java prefiere ampliar un tipo primitivo antes que convertirlo mediante autoboxing a un tipo envoltorio. Esto puede producir resultados inesperados.

static void display(long n)    { System.out.println("long: " + n); }
static void display(Integer n) { System.out.println("Integer: " + n); }

int x = 100;
display(x); // long: 100 — widens int to long BEFORE autoboxing to Integer
// This surprises many developers!

static void show(Long n)    { System.out.println("Long"); }
static void show(Integer n) { System.out.println("Integer"); }

// show(100); // compile error — ambiguous! Neither is more specific

Ambigüedad con el argumento null

Pasar null a métodos sobrecargados puede resultar ambiguo si varios métodos aceptan tipos de referencia. Convierta null explícitamente para resolver la ambigüedad.

static void handle(String s)  { System.out.println("String: " + s); }
static void handle(Integer i) { System.out.println("Integer: " + i); }
static void handle(Object o)  { System.out.println("Object"); }

handle((String) null);  // String: null (cast resolves ambiguity)
handle((Integer) null); // Integer: null
// handle(null);        // compile error: ambiguous (String vs Integer)

Sobrecarga con herencia

La resolución de métodos considera el tipo declarado de la variable de referencia, no el tipo en tiempo de ejecución; esta es una decisión que se toma en tiempo de compilación.

class Animal {}
class Dog extends Animal {}

static void greet(Animal a) { System.out.println("Animal"); }
static void greet(Dog d)    { System.out.println("Dog"); }

Animal a = new Dog(); // declared as Animal
greet(a);   // Animal — compile-time type is Animal!

Dog d = new Dog();
greet(d);   // Dog — compile-time type is Dog

Sobrecarga frente a sobrescritura

La sobrecarga se decide en tiempo de compilación (despacho estático). La sobrescritura se decide en tiempo de ejecución (despacho dinámico) según el tipo real del objeto.

class Base {
    void run() { System.out.println("Base.run"); }
}
class Sub extends Base {
    @Override
    void run() { System.out.println("Sub.run"); } // overriding

    void run(int speed) { System.out.println("Sub.run(" + speed + ")"); } // overloading
}

Base b = new Sub();
b.run();     // Sub.run — override (runtime dispatch)
// b.run(10); // compile error — Base doesn't have run(int)

Patrones habituales de sobrecarga

Usos habituales de la sobrecarga en las API: proporcionar métodos de conveniencia que delegan en una versión con todos los parámetros.

class Connection {
    void connect(String host, int port, int timeout) {
        System.out.println("Connecting to " + host + ":" + port + " timeout=" + timeout);
    }

    // Convenience overloads
    void connect(String host, int port) {
        connect(host, port, 30); // delegate with default timeout
    }

    void connect(String host) {
        connect(host, 5432); // delegate with default port
    }
}

new Connection().connect("db.example.com");
// Connecting to db.example.com:5432 timeout=30

Sobrecarga y genéricos

La sobrecarga de métodos genéricos requiere cuidado: el borrado de tipos puede hacer que dos firmas aparentemente distintas sean idénticas después de la compilación.

// Type erasure problem: both methods erase to the same signature!
// static void process(List<String> list) {} // compile error
// static void process(List<Integer> list) {} // duplicate after erasure

// Solutions:
// 1. Use different method names: processStrings / processIntegers
// 2. Use a generic method with bounded type:
static <T extends Number> void processNumbers(List<T> list) {
    list.forEach(n -> System.out.println(n.doubleValue()));
}
processNumbers(List.of(1, 2, 3));
processNumbers(List.of(1.5, 2.5));

En la práctica: sobrecargas con estilo Builder

La sobrecarga es habitual en las API de tipo builder o factory para proporcionar una creación flexible de objetos.

class Notification {
    final String title, body;
    final String imageUrl;
    final boolean urgent;

    // Factory overloads for convenience
    static Notification simple(String title, String body) {
        return new Notification(title, body, null, false);
    }
    static Notification urgent(String title, String body) {
        return new Notification(title, body, null, true);
    }
    static Notification withImage(String title, String body, String url) {
        return new Notification(title, body, url, false);
    }
    Notification(String title, String body, String imageUrl, boolean urgent) {
        this.title = title; this.body = body;
        this.imageUrl = imageUrl; this.urgent = urgent;
    }
}

Errores habituales de la sobrecarga

Evite estos errores habituales de la sobrecarga:

  • Demasiadas sobrecargas para la misma operación: utilice un builder en su lugar
  • Sobrecargas que solo se diferencian en el orden de los parámetros: resultan confusas
  • Ampliación inesperada: un int puede resolverse como long en lugar de Integer
// Confusing: order-based overloads
// void save(String name, int age)  {}
// void save(int age, String name)  {} // very confusing!

// Better: use a record/DTO
record UserData(String name, int age) {}
void save(UserData data) {}

// Surprising widening
static void m(long x)   { System.out.println("long"); }
static void m(Integer x){ System.out.println("Integer"); }
int v = 5;
m(v); // long! widening preferred over autoboxing

Comprobación rápida

Si un método está sobrecargado con parámetros long y Integer, ¿cuál se elige al pasar un argumento int?

Repaso: reglas de sobrecarga de métodos

Conceptos clave:

  • La sobrecarga se diferencia por la cantidad, el tipo o el orden de los parámetros, pero NO únicamente por el tipo de retorno
  • Java resuelve las sobrecargas en tiempo de compilación mediante el tipo declarado de los argumentos
  • Se prefiere ampliar un tipo primitivo antes que convertirlo automáticamente a una clase envolvente
  • Los argumentos null pueden causar ambigüedad; realice una conversión explícita para resolverla: handle((String) null)
  • La sobrecarga ocurre en tiempo de compilación; la sobrescritura ocurre en tiempo de ejecución: son mecanismos diferentes
  • Utilice sobrecargas prácticas que deleguen en un método maestro con todos los parámetros

Preguntas frecuentes

¿La lección «Reglas de sobrecarga de métodos» es gratis?

Sí — el texto completo de «Reglas de sobrecarga de métodos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Reglas de sobrecarga de métodos»?

Comprenda cómo Java resuelve los métodos sobrecargados y cuáles son los problemas habituales de ambigüedad. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Java Academy?

No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Reglas de sobrecarga de métodos»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Java Academy?

Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Reglas de sobrecarga de métodos
  2. Parámetros varargs
  3. Campos estáticos y constantes
  4. Clases de utilidades y métodos de fábrica estáticos
← Volver a Java Academy