Sobes.tech
Junior
196

V jakých případech lze použít modifikátor final v Java?

Odpověď od AI

sobes.tech AI

Modifikátor final v jazyce Java lze použít na:

  1. Proměnné:

    • Lokální proměnné: Jejich hodnota je přiřazena jednou a po inicializaci již nemůže být změněna.
    • Políčka třídy: Hodnota pole je přiřazena při deklaraci nebo v konstruktoru a poté již nemůže být změněna.
    • Parametry metody: Parametr uvnitř metody se stává konstantou; nelze jej znovu přiřadit uvnitř těla metody.

    Použití final u proměnných zajišťuje:

    • Neměnnost: Záruka, že hodnota se nezmění.
    • Bezpečnost vláken: final pole třídy jsou automaticky viditelná všem vláknům po dokončení konstruktoru bez dodatečné synchronizace.
    • Optimalizace překladače: Překladač může provádět určité optimalizace s vědomím, že hodnota se nezmění.
  2. Metody:

    • Metoda deklarovaná jako final nemůže být přepsána v podtřídách.
    • To je užitečné pro:
      • Zabránění nechtěným změnám chování: Zajišťuje, že logika metody zůstane neměnná.
      • Podpora kompozice: Podporuje použití kompozice místo dědičnosti.
      • Možné optimalizace překladače: Překladač může provádět inline rozbalení volání final metod.
  3. Třídy:

    • Třída deklarovaná jako final nemůže mít podtřídy.
    • Použití final u třídy je určeno k:
      • Vytváření neměnných (immutable) tříd: Například třídy obalů pro primitivní typy (Integer, String).
      • Ochrana návrhu: Zabraňuje rozšíření, které by mohlo narušit invarianty třídy.
      • Zvýšení bezpečnosti: Zajišťuje, že chování třídy nelze změnit vytvářením podtříd.
Použití Popis Výhody
final pole Hodnota je přiřazena jednou (při deklaraci nebo v konstruktoru). Neměnnost, bezpečnost vláken, optimalizace.
final parametr Hodnota nemůže být změněna uvnitř metody. Jasná signatura, záruka neměnnosti hodnoty parametru.
final metoda Nemůže být přepsána v podtřídách. Zabránění změn chování, podpora kompozice, optimalizace.
final třída Nemůže mít podtřídy (nelze dědit). Neměnná třída, ochrana návrhu, zvýšení bezpečnosti.

Příklady:

public class Example {
    // final pole
    private final String name;

    // final primitivní pole
    private final int id;

    // final, ale může odkazovat na různé objekty typu List
    private final List<String> items;

    // Konstantní hodnota při kompilaci
    public static final double PI = 3.14159;

    public Example(String name, int id) {
        this.name = name; // přiřazení do final pole
        this.id = id; // přiřazení do final pole
        this.items = new ArrayList<>(); // inicializace final pole seznamu
    }

    // final metoda
    public final void printDetails() {
        System.out.println("Name: " + name + ", ID: " + id);
    }

    // metoda s final parametrem
    public void addItem(final String item) {
        // item = "nový prvek"; // chyba při kompilaci: Cannot assign a value to final variable 'item'
        items.add(item);
    }
}

// final třída
// public final class ImmutableClass {
//     private final int value;
//
//     public ImmutableClass(int value) {
//         this.value = value;
//     }
//
//     public int getValue() {
//         return value;
//     }
// }

// public class SubclassOfImmutable extends ImmutableClass { // Chyba při kompilaci: Cannot inherit from final class
// }