Menu
CoddyTech

Ключевое слово final

Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy. Урок 13 из 87.

Ключевое слово final в Java предотвращает изменение. Его можно применять к переменным, методам и классам, и в каждом случае эффект будет разным.

При применении к переменной final делает её константой: после присваивания её значение нельзя изменить:

public class Circle {
    private final double PI = 3.14159;
    private final double radius;
    
    public Circle(double radius) {
        this.radius = radius;  // Можно присвоить значение один раз в конструкторе
    }
    
    public void setRadius(double r) {
        // this.radius = r;  // Ошибка! Нельзя повторно присвоить значение final-переменной
    }
}

Переменная final должна быть инициализирована либо при объявлении, либо в конструкторе. После этого любая попытка присвоить ей другое значение приводит к ошибке компиляции.

Для ссылочных типов final означает, что ссылка не может указывать на другой объект, но содержимое объекта всё ещё может изменяться:

private final StringBuilder name = new StringBuilder("John");

// name = new StringBuilder("Jane");  // Ошибка! Нельзя присвоить новое значение
name.append(" Doe");  // OK! Содержимое объекта можно изменить

Использование final с полями ясно выражает намерение — это сообщает другим разработчикам, что это значение не должно меняться после инициализации. Это особенно полезно для значений конфигурации, идентификаторов или любых данных, которые должны оставаться неизменными на протяжении всего срока жизни объекта.

final метод нельзя переопределить в подклассе:

class Base {
    public final void greet() {
        System.out.println("Hi");
    }
}
class Child extends Base {
    // public void greet() { }  // Ошибка! greet() объявлен final в Base
}

Класс final вообще нельзя расширить. String — финальный класс, поэтому ни один класс не может его расширить:

final class Config { }
// class MyConfig extends Config { }  // Ошибка! Config — финальный класс
challenge icon

Задание

Легко

Давайте создадим систему регистрации Student, которая использует ключевое слово final, чтобы защитить данные, которые никогда не должны изменяться после регистрации студента.

Вы создадите два файла, чтобы организовать свой код:

  • Student.java: создайте класс Student, в котором некоторые сведения после задания будут навсегда заблокированы:
    • Поле final studentId (String) — задаётся при создании и никогда не может измениться
    • Поле final enrollmentYear (int) — год зачисления студента, который также не меняется
    • Обычное приватное поле name (String) — его можно обновить, если студент изменит имя
    • Конструктор, который принимает все три значения и инициализирует поля
    • Геттер getStudentId() для идентификатора студента
    • Геттер getEnrollmentYear() для года зачисления
    • Геттер getName() и сеттер setName() для имени
    • Метод getInfo(), который возвращает: "ID: [studentId] | Name: [name] | Enrolled: [enrollmentYear]"
  • Main.java: создайте объект Student, затем обновите его имя и выведите информацию о нём. Вы получите четыре входных значения: идентификатор студента, исходное имя, год зачисления и новое имя. Выведите две строки:
    • Информация о студенте до изменения имени
    • Информация о студенте после изменения имени

Вы получите четыре входных значения в следующем порядке: studentId (String), name (String), enrollmentYear (int) и newName (String).

Обратите внимание, как поля final защищают идентификатор студента и год зачисления: это постоянные записи, которые не должны меняться, тогда как имя можно обновить с помощью сеттера.

Попробуйте сами

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Считайте входные данные
        String studentId = scanner.nextLine();
        String name = scanner.nextLine();
        int enrollmentYear = scanner.nextInt();
        scanner.nextLine(); // считайте символ новой строки
        String newName = scanner.nextLine();
        
        // TODO: Создайте объект Student с начальными значениями
        
        // TODO: Выведите информацию о студенте до изменения имени
        
        // TODO: Обновите имя студента с помощью сеттера
        
        // TODO: Выведите информацию о студенте после изменения имени
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Java