Java Academy · Lektion

Fullständig switch över sealed

Fullständighet vid kompilering.

Lektion 4 av 413 steg

Fullständig switch över sealed är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 4 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.

Uttömmande switch

När Ni använder switch över en sealed-typ känner kompilatorn till varje tillåten undertyp. Om switch-satsen täcker alla är den uttömmande och Ni behöver ingen default-gren.

En switch med typmönster

Switch-uttryck kan matcha på körtidstypen för ett sealed-värde med hjälp av typmönster.

public class Main {
    sealed interface Shape permits Circle, Square {}
    record Circle(double radius) implements Shape {}
    record Square(double side) implements Shape {}

    static String describe(Shape s) {
        return switch (s) {
            case Circle c -> "circle r=" + c.radius();
            case Square sq -> "square s=" + sq.side();
        };
    }

    public static void main(String[] args) {
        System.out.println(describe(new Circle(2)));
        System.out.println(describe(new Square(3)));
    }
}

Ingen default behövs

Eftersom Circle och Square är de enda tillåtna undertyperna accepterar kompilatorn switch-satsen som komplett. Att lägga till en default skulle vara överflödigt.

Fullständighet vid kompilering

Om Ni senare lägger till en ny tillåten undertyp och glömmer att hantera den, kompileras inte någon uttömmande switch. På så sätt omvandlas en hel kategori av körningsfel till kompileringsfel.

Beräkna ett resultat

Uttömmande switch-uttryck passar utmärkt för att omvandla ett värde till ett resultat, till exempel en area.

public class Main {
    sealed interface Shape permits Circle, Square {}
    record Circle(double radius) implements Shape {}
    record Square(double side) implements Shape {}

    static double area(Shape s) {
        return switch (s) {
            case Circle c -> Math.PI * c.radius() * c.radius();
            case Square sq -> sq.side() * sq.side();
        };
    }

    public static void main(String[] args) {
        System.out.printf("%.2f%n", area(new Circle(1)));
        System.out.printf("%.2f%n", area(new Square(2)));
    }
}

Switch-satser kontra switch-uttryck

Uttömmandehet gäller för switch-uttryck (sådana som ger ett värde) och för switch-satser som använder pilformen på en sealed-typ. Kompilatorn kräver full täckning.

Hantera null

Som standard kastar en switch över en referens NullPointerException om värdet är null. Ni kan lägga till etiketten case null för att hantera det uttryckligen.

public class Main {
    sealed interface Shape permits Circle, Square {}
    record Circle(double radius) implements Shape {}
    record Square(double side) implements Shape {}

    static String describe(Shape s) {
        return switch (s) {
            case null -> "no shape";
            case Circle c -> "circle";
            case Square sq -> "square";
        };
    }

    public static void main(String[] args) {
        System.out.println(describe(null));
        System.out.println(describe(new Circle(1)));
    }
}

Guard-villkor bryter inte uttömmandet

Ni kan lägga till when-villkor för att förfina fallen, men ett villkorat fall räcker inte ensamt för att täcka en typ. Ni behöver fortfarande ett ovillkorat fall för varje undertyp för att switch-satsen ska förbli uttömmande.

public class Main {
    sealed interface Shape permits Circle, Square {}
    record Circle(double radius) implements Shape {}
    record Square(double side) implements Shape {}

    static String size(Shape s) {
        return switch (s) {
            case Circle c when c.radius() > 10 -> "big circle";
            case Circle c -> "small circle";
            case Square sq -> "square";
        };
    }

    public static void main(String[] args) {
        System.out.println(size(new Circle(20)));
        System.out.println(size(new Circle(2)));
    }
}

Switch på en sealed-klass

Samma uttömmandehet fungerar för sealed-klasser, inte bara för gränssnitt.

public class Main {
    sealed static abstract class Token permits Word, Number {}
    static final class Word extends Token { final String text; Word(String t){text=t;} }
    static final class Number extends Token { final int value; Number(int v){value=v;} }

    static String show(Token t) {
        return switch (t) {
            case Word w -> "word:" + w.text;
            case Number n -> "num:" + n.value;
        };
    }

    public static void main(String[] args) {
        System.out.println(show(new Word("hi")));
        System.out.println(show(new Number(7)));
    }
}

Varför detta är kraftfullt

Uttömmande switch tillsammans med sealed-typer ger säker kod som tål förändringar. Uppsättningen fall dokumenteras på ett ställe, och kompilatorn garanterar att Ni aldrig missar något när modellen växer.

Ett komplett exempel

Här omvandlas en sealed-resultattyp till ett meddelande med full täckning.

public class Main {
    sealed interface Result permits Ok, Err {}
    record Ok(int value) implements Result {}
    record Err(String message) implements Result {}

    static String render(Result r) {
        return switch (r) {
            case Ok ok -> "value = " + ok.value();
            case Err err -> "error: " + err.message();
        };
    }

    public static void main(String[] args) {
        System.out.println(render(new Ok(10)));
        System.out.println(render(new Err("bad input")));
    }
}

Snabbtest

Testa er förståelse av uttömmande switch.

Sammanfattning

Ni har lärt er att använda uttömmande switch med sealed-typer.

  • Om alla tillåtna undertyper täcks blir switch-satsen uttömmande, så ingen default behövs.
  • En ny undertyp som inte hanteras blir ett kompileringsfel.
  • case null hanterar null-värden uttryckligen.
  • Guard-villkor förfinar ett fall men ersätter inte ett ovillkorat fall.
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 ”Fullständig switch över sealed” gratis?

Ja – hela texten till ”Fullständig switch över sealed” 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 ”Fullständig switch över sealed”?

Fullständighet vid kompilering. 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 4 av 4.

Hur lång tid tar lektionen ”Fullständig switch över sealed”?

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. Deklarera sealed-typer
  2. Satsen permits
  3. Sealed med records
  4. Fullständig switch över sealed
← Tillbaka till Java Academy