Java Academy · Lektion

Regler för metodöverlagring

Förstå hur Java avgör vilken överlagrad metod som ska användas och vilka vanliga tvetydighetsproblem som finns.

Lektion 1 av 413 steg

Regler för metodöverlagring är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Java Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Java Academy innehåller totalt 4 lektioner.

Regler för metodöverlagring

Metodöverlagring låter er definiera flera metoder med samma namn men olika parameterlistor. Java väljer den bästa matchningen vid kompilering enligt exakta regler för metodupplösning.

Vad är överlagring?

Överlagrade metoder delar namn men skiljer sig åt genom antal parametrar, typ eller ordning. Returtypen ensam räcker INTE för överlagring.

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)

Upplösning: den mest specifika matchningen

Java väljer den mest specifika tillämpliga metoden. Typbreddning, autoboxning och varargs prövas i prioriterad ordning.

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)

Typbreddning före autoboxning

Java föredrar att bredda en primitiv typ framför att autoboxa den till en wrapper-typ. Detta kan ge överraskande resultat.

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

Tvetydighet med null-argument

Att skicka null till överlagrade metoder kan vara tvetydigt om flera metoder accepterar referenstyper. Typomvandla null för att lösa tvetydigheten.

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)

Överlagring med arv

Metodupplösningen tar hänsyn till referensvariabelns deklarerade typ, inte körtypen — detta avgörs vid kompilering.

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

Överlagring kontra överskuggning

Överlagring avgörs vid kompilering (statisk dispatch). Överskuggning avgörs vid körning (dynamisk dispatch) utifrån objektets faktiska typ.

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)

Vanliga mönster för överlagring

Vanliga användningsområden för överlagring i API:er är att tillhandahålla bekvämlighetsmetoder som delegerar till en version med alla parametrar.

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

Överlagring och generiska typer

Överlagring av generiska metoder kräver omsorg — typutplåning kan göra två signaturer som verkar olika identiska efter kompilering.

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

I praktiken: överlagringar i builder-stil

Överlagring är vanligt i builder- och factory-API:er för att möjliggöra flexibel objektskapning.

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;
    }
}

Fallgropar vid överlagring

Undvik följande vanliga misstag vid överlagring:

  • För många överlagringar för samma operation — använd i stället en builder
  • Överlagringar som endast skiljer sig åt genom parameterordningen — förvirrande
  • Överraskande typbreddning: en int kan matcha long i stället för 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

Snabbkontroll

Om en metod är överlagrad med parametrar av både long- och Integer-typ, vilken väljs när ett int-argument skickas?

Sammanfattning: regler för metodöverlagring

Viktiga slutsatser:

  • Överlagring skiljer sig åt genom antal parametrar, typ eller ordning – INTE enbart returtypen
  • Java löser överlagringar vid kompilering med hjälp av argumentens deklarerade typer
  • Utvidgning av en primitiv typ föredras framför att omvandla den till en wrapperklass genom autoboxing
  • null-argument kan orsaka tvetydighet – använd en typkonvertering för att lösa det: handle((String) null)
  • Överlagring sker vid kompilering, medan överskuggning sker vid körning – det är olika mekanismer
  • Använd bekvämlighetsöverlagringar som delegerar till en huvudmetod med alla parametrar
Gratis att börja

Lär dig Java med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
104
Lektioner
374

Vanliga frågor

Är lektionen ”Regler för metodöverlagring” gratis?

Ja – hela texten till ”Regler för metodöverlagring” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Java Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Java Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Regler för metodöverlagring”?

Förstå hur Java avgör vilken överlagrad metod som ska användas och vilka vanliga tvetydighetsproblem som finns. Ni övar på Java Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Java Academy?

Du behöver inga förkunskaper. Utbildningen i Java Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.

Hur lång tid tar lektionen ”Regler för metodöverlagring”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Java Academy-lektionen?

Ja. Varje Java Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Regler för metodöverlagring
  2. Varargs-parametrar
  3. Statiska fält och konstanter
  4. Hjälpklasser och statiska fabriksmetoder
← Tillbaka till Java Academy