0Pricing
Java Academy · Aula

Regras de Sobrecarga de Métodos

Compreenda como Java resolve métodos sobrecarregados e conheça as armadilhas comuns de ambiguidade.

Regras de Sobrecarga de Métodos é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.

Regras de sobrecarga de métodos

A sobrecarga de métodos permite definir vários métodos com o mesmo nome, mas com listas de parâmetros diferentes. Java seleciona a melhor correspondência em tempo de compilação usando regras precisas de resolução.

O que é sobrecarga

Os métodos sobrecarregados compartilham um nome, mas diferem na quantidade, no tipo ou na ordem dos parâmetros. O tipo de retorno, por si só, não é suficiente (NOT) para fazer sobrecarga.

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)

Resolução: a correspondência mais específica

Java escolhe o método aplicável mais específico. O alargamento, o autoboxing e os argumentos variáveis são tentados nessa ordem de preferência.

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)

Alargamento antes do autoboxing

Java prefere alargar um tipo primitivo a convertê-lo por autoboxing em um tipo de encapsulamento. Isso pode produzir resultados surpreendentes.

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

Ambiguidade com o argumento nulo

Passar null para métodos sobrecarregados pode ser ambíguo se vários métodos aceitarem tipos de referência. Faça a conversão explícita de null para resolver a ambiguidade.

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 com herança

A resolução de métodos considera o tipo declarado da variável de referência, não o tipo em tempo de execução — essa é uma decisão tomada em tempo de compilação.

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 versus sobrescrita

A sobrecarga é uma decisão em tempo de compilação (despacho estático). A sobrescrita é uma decisão em tempo de execução (despacho dinâmico) baseada no tipo real do 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)

Padrões comuns de sobrecarga

Usos comuns da sobrecarga em APIs: fornecer métodos de conveniência que delegam a uma versão com todos os 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 e genéricos

A sobrecarga de métodos genéricos exige cuidado — o apagamento de tipos pode tornar duas assinaturas aparentemente diferentes idênticas após a compilação.

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

Prático: sobrecargas no estilo de construção

A sobrecarga é comum em APIs de construção e fábrica para oferecer uma criação flexível 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;
    }
}

Armadilhas da sobrecarga

Evite estes erros comuns de sobrecarga:

  • Excesso de sobrecargas para a mesma operação — use um construtor em vez disso
  • Sobrecargas que diferem apenas na ordem dos parâmetros — isso causa confusão
  • Alargamento surpreendente: um int pode ser resolvido como long em vez 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

Verificação rápida

Se um método estiver sobrecarregado com parâmetros long e Integer, qual será escolhido ao passar um argumento int?

Recapitulação: regras de sobrecarga de métodos

Principais conclusões:

  • A sobrecarga difere pela quantidade, pelo tipo ou pela ordem dos parâmetros — não apenas pelo tipo de retorno (NOT)
  • Java resolve as sobrecargas em tempo de compilação usando o tipo declarado dos argumentos
  • O alargamento de um tipo primitivo tem preferência sobre sua conversão automática para um tipo encapsulador
  • Argumentos nulos podem causar ambiguidade — faça uma conversão explícita para resolver: handle((String) null)
  • A sobrecarga ocorre em tempo de compilação; a sobrescrita ocorre em tempo de execução — são mecanismos diferentes
  • Use sobrecargas convenientes que deleguem para um método principal com todos os parâmetros

Perguntas Frequentes

A aula “Regras de Sobrecarga de Métodos” é grátis?

Sim — o texto completo de “Regras de Sobrecarga de Métodos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.

O que vou aprender em “Regras de Sobrecarga de Métodos”?

Compreenda como Java resolve métodos sobrecarregados e conheça as armadilhas comuns de ambiguidade. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Java Academy?

Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Regras de Sobrecarga de Métodos”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Java Academy?

Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Regras de Sobrecarga de Métodos
  2. Parâmetros Varargs
  3. Campos e Constantes Estáticos
  4. Classes Utilitárias e Métodos de Fábrica Estáticos
← Voltar para Java Academy