Regeln für Methodenüberladung
Verstehen Sie, wie Java überladene Methoden auflöst und welche häufigen Probleme durch Mehrdeutigkeiten entstehen.
Regeln für Methodenüberladung ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Regeln für Methodenüberladung
Mit Methodenüberladung können Sie mehrere Methoden mit demselben Namen, aber unterschiedlichen Parameterlisten definieren. Java wählt zur Kompilierzeit mithilfe präziser Auflösungsregeln die beste Übereinstimmung aus.
Was ist Überladung?
Überladene Methoden haben denselben Namen, unterscheiden sich aber in der Anzahl, dem Typ oder der Reihenfolge ihrer Parameter. Der Rückgabetyp allein reicht NICHT für eine Überladung aus.
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)Auflösung: die spezifischste Übereinstimmung
Java wählt die spezifischste anwendbare Methode aus. Erweiterung, Autoboxing und Varargs werden in dieser bevorzugten Reihenfolge berücksichtigt.
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)Erweiterung vor Autoboxing
Java bevorzugt die Erweiterung eines primitiven Typs gegenüber der Umwandlung in einen Wrapper durch Autoboxing. Das kann zu überraschenden Ergebnissen führen.
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 specificMehrdeutigkeit bei null-Argumenten
Die Übergabe von null an überladene Methoden kann mehrdeutig sein, wenn mehrere Methoden Referenztypen akzeptieren. Wandeln Sie null in den gewünschten Typ um, um die Mehrdeutigkeit aufzulösen.
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)Überladung bei Vererbung
Bei der Methodenauflösung wird der deklarierte Typ der Referenzvariablen berücksichtigt, nicht der Laufzeittyp – dies ist eine Entscheidung zur Kompilierzeit.
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Überladung im Vergleich zu Überschreiben
Überladung ist eine Entscheidung zur Kompilierzeit (statische Bindung). Überschreiben ist eine Entscheidung zur Laufzeit (dynamische Bindung), die auf dem tatsächlichen Objekttyp basiert.
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)Gängige Muster für Überladungen
Eine häufige Verwendung von Überladungen in APIs sind Komfortmethoden, die eine Variante mit vollständiger Parameterliste aufrufen.
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Überladung und Generics
Bei der Überladung generischer Methoden ist Vorsicht erforderlich – durch Typlöschung können zwei scheinbar unterschiedliche Signaturen nach der Kompilierung identisch sein.
// 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));Praxisbeispiel: Überladungen im Builder-Stil
Überladungen sind in Builder- und Factory-APIs üblich, um eine flexible Objekterstellung zu ermöglichen.
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;
}
}Fallstricke bei Überladungen
Vermeiden Sie diese häufigen Fehler bei Überladungen:
- Zu viele Überladungen für dieselbe Operation – verwenden Sie stattdessen einen Builder
- Überladungen, die sich nur in der Parameterreihenfolge unterscheiden – das ist verwirrend
- Überraschende Erweiterung: Ein int kann zu long statt zu Integer aufgelöst werden
// 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 autoboxingSchnelltest
Wenn eine Methode sowohl mit Parametern vom Typ long als auch vom Typ Integer überladen ist, welche Variante wird beim Übergeben eines Arguments vom Typ int gewählt?
Zusammenfassung: Regeln für die Methodenüberladung
Die wichtigsten Erkenntnisse:
- Überladung unterscheidet sich durch Anzahl, Typ oder Reihenfolge der Parameter – NICHT allein durch den Rückgabetyp
- Java löst Überladungen zur Kompilierzeit anhand des deklarierten Typs der Argumente auf
- Das Erweitern eines primitiven Datentyps wird dem Autoboxing zu einem Wrapper-Typ vorgezogen
null-Argumente können Mehrdeutigkeiten verursachen – zur Auflösung casten: handle((String) null)- Überladen wird zur Kompilierzeit aufgelöst, Überschreiben zur Laufzeit – es handelt sich um unterschiedliche Mechanismen
- Verwenden Sie praktische Überladungen, die eine Methode mit vollständiger Parameterliste delegieren
Häufig gestellte Fragen
Ist die Lektion „Regeln für Methodenüberladung“ kostenlos?
Ja — der vollständige Text von „Regeln für Methodenüberladung“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Regeln für Methodenüberladung“?
Verstehen Sie, wie Java überladene Methoden auflöst und welche häufigen Probleme durch Mehrdeutigkeiten entstehen. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Java Academy zu starten?
Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „Regeln für Methodenüberladung“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?
Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Regeln für Methodenüberladung
- Varargs-Parameter
- Statische Felder und Konstanten
- Utility-Klassen und statische Factory-Methoden