Java Academy · Lektion

Lokala och anonyma klasser

Deklarera klasser i metoder och skapa anonyma implementationer av gränssnitt direkt vid behov.

Lektion 3 av 413 steg

Lokala och anonyma klasser är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 3 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.

Lokala och anonyma klasser

Lokala klasser definieras inuti en metod. Anonyma klasser är lokala klasser utan namn – de kombinerar klassdeklaration och instansiering. Båda fångar lokala variabler som är effectively final.

Deklaration av lokal klass

En lokal klass deklareras inuti en metodkropp. Den kan komma åt medlemmar i den omslutande klassen och lokala variabler som är effectively final.

static void greet(String language) {
    // Local class — defined inside the method
    class Greeter {
        String sayHello(String name) {
            // Can access 'language' — it is effectively final
            return switch (language) {
                case "EN" -> "Hello, " + name;
                case "ES" -> "Hola, " + name;
                case "FR" -> "Bonjour, " + name;
                default   -> "Hi, " + name;
            };
        }
    }

    Greeter g = new Greeter();
    System.out.println(g.sayHello("Alice"));
}
greet("ES"); // Hola, Alice

Variabler som är effectively final

Lokala och anonyma klasser kan endast fånga lokala variabler som är effectively final – de tilldelas aldrig på nytt efter initieringen.

void process(int threshold) {
    // threshold is effectively final (never reassigned)
    Runnable r = new Runnable() {
        public void run() {
            System.out.println("Threshold: " + threshold);
        }
    };
    r.run();

    // threshold = 10; // If you add this, the anonymous class won't compile
}

Grunderna i anonyma klasser

En anonym klass implementerar ett gränssnitt eller utökar en klass direkt i ett enda uttryck.

interface Comparator<T> {
    int compare(T a, T b);
}

// Anonymous class implementing Comparator
java.util.Comparator<String> byLength = new java.util.Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return Integer.compare(a.length(), b.length());
    }
};

List<String> words = new ArrayList<>(List.of("banana", "fig", "apple", "kiwi"));
words.sort(byLength);
System.out.println(words); // [fig, kiwi, apple, banana]

Anonym klass jämfört med lambda

För gränssnitt med en enda abstrakt metod (SAM-gränssnitt) ersätter lambdauttryck anonyma klasser. Anonyma klasser behövs fortfarande för gränssnitt med flera metoder eller när abstrakta klasser utökas.

// Anonymous class for single-method interface
Runnable r1 = new Runnable() {
    public void run() { System.out.println("Running!"); }
};

// Lambda — cleaner for SAM interfaces
Runnable r2 = () -> System.out.println("Running!");

// Must use anonymous class for multi-method interface:
java.io.FilenameFilter filter = new java.io.FilenameFilter() {
    public boolean accept(java.io.File dir, String name) {
        return name.endsWith(".java");
    }
}; // FilenameFilter is not a SAM — no lambda shorthand

Anonym klass med tillstånd

Anonyma klasser kan ha fält, till skillnad från lambdauttryck. Det är användbart när tillstånd behöver bevaras i den anonyma implementationen.

interface Counter { int increment(); int get(); }

Counter counter = new Counter() {
    private int count = 0;

    public int increment() { return ++count; }
    public int get()       { return count; }
};

System.out.println(counter.increment()); // 1
System.out.println(counter.increment()); // 2
System.out.println(counter.get());       // 2

Mönstret med anonym lyssnare

Innan lambdauttryck introducerades var anonyma klasser det vanliga mönstret för eventlyssnare i GUI- och Android-programmering.

// Modern Android/Swing style: anonymous class listener
Button loginButton = new Button(); // hypothetical
loginButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick() {
        System.out.println("Login button clicked!");
    }
});

// Modern equivalent with lambda (if OnClickListener is SAM):
loginButton.setOnClickListener(() -> System.out.println("Clicked!"));

Lokal klass för komplex logik

Lokala klasser passar bra när en klass med flera metoder behövs på en enda plats – logiken är för komplex för ett lambdauttryck men för specifik för en klass på toppnivå.

static List<String> processData(List<String> data, String prefix) {
    // Local class: complex enough for a class, used only here
    class DataProcessor {
        List<String> result = new ArrayList<>();

        void process(String item) {
            // prefix is effectively final
            if (item.startsWith(prefix)) {
                result.add(item.toUpperCase());
            }
        }
    }
    DataProcessor dp = new DataProcessor();
    data.forEach(dp::process);
    return dp.result;
}
System.out.println(processData(List.of("apple","avocado","banana"), "a"));
// [APPLE, AVOCADO]

Anonym klass för abstrakt klass

Anonyma klasser kan utöka abstrakta klasser och skriva över abstrakta metoder utan att en namngiven underklass skapas.

abstract class ReportFormatter {
    abstract String formatHeader(String title);
    abstract String formatBody(List<String> rows);

    String format(String title, List<String> rows) {
        return formatHeader(title) + "\n" + formatBody(rows);
    }
}

ReportFormatter csvFormatter = new ReportFormatter() {
    public String formatHeader(String t) { return "\"" + t + "\""; }
    public String formatBody(List<String> rows) {
        return String.join("\n", rows);
    }
};
System.out.println(csvFormatter.format("Sales", List.of("a,1","b,2")));

Anti-mönstret double-brace initialization

Tricket double-brace initialization använder anonyma klasser för att initiera samlingar. Det skapar en underklass med en instansinitierare. Undvik det – det är ineffektivt och felbenäget.

// Anti-pattern: double-brace initialization
Map<String, Integer> map = new HashMap<String, Integer>() {{
    put("a", 1);
    put("b", 2);
}};
// Creates an anonymous HashMap subclass — wasteful!

// GOOD: use Map.of() or Map.ofEntries()
Map<String, Integer> better = Map.of("a", 1, "b", 2);

// Or a mutable map:
Map<String, Integer> mutable = new HashMap<>(Map.of("a", 1, "b", 2));

Välja mellan lambda, anonym och lokal klass

Vägledning för valet:

  • Lambda: en enda abstrakt metod, inget extra tillstånd och inget arv
  • Anonym klass: flera metoder, behov av tillstånd eller utökning av en abstrakt klass
  • Lokal klass: återanvändning inom metoden, flera metoder eller komplext tillstånd

Snabb kontroll

Vad gör en anonym klass alltid i ett enda uttryck?

Sammanfattning: Lokala och anonyma klasser

Viktiga lärdomar:

  • Lokala klasser definieras inuti metoder och kan komma åt lokala variabler som är effectively final
  • Anonyma klasser kombinerar klassdeklaration och instansiering i ett enda uttryck
  • Anonyma klasser kan ha fält och flera metoder – till skillnad från lambdauttryck
  • Lambdauttryck ersätter anonyma klasser för gränssnitt med en enda abstrakt metod
  • Använd lokala klasser när logiken är tillräckligt komplex för en klass men specifik för en enda metod
  • Undvik double-brace initialization – det skapar onödiga anonyma underklasser
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 ”Lokala och anonyma klasser” gratis?

Ja – hela texten till ”Lokala och anonyma klasser” 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 ”Lokala och anonyma klasser”?

Deklarera klasser i metoder och skapa anonyma implementationer av gränssnitt direkt vid behov. 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 3 av 4.

Hur lång tid tar lektionen ”Lokala och anonyma klasser”?

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. Statiska nästlade klasser
  2. Inre klasser och åtkomst till yttre klasser
  3. Lokala och anonyma klasser
  4. Välj rätt nästlingsstrategi
← Tillbaka till Java Academy