Ответ
Модификатор final используется для объявления переменной, которая может быть инициализирована только один раз. После присвоения значения его нельзя изменить. Это обеспечивает безопасность и ясность кода, явно указывая на намерение использовать переменную как константу в рамках её области видимости.
Основные случаи использования:
- Константы времени выполнения: Значение вычисляется при запуске программы и затем фиксируется.
- Защита от изменений: Гарантирует, что ссылка на объект (или значение примитива) не будет переприсвоена.
- Оптимизация: Помогает компилятору в некоторых оптимизациях, хотя в меньшей степени, чем
const.
Примеры:
// 1. Инициализация при объявлении
final String apiBaseUrl = 'https://api.example.com';
// apiBaseUrl = '...'; // Ошибка компиляции: 'apiBaseUrl' может быть установлена только один раз.
// 2. Инициализация в конструкторе (для полей класса)
class User {
final String id;
final String name;
User(this.id, this.name); // Значения присваиваются один раз при создании объекта
// Ошибка: final поле не может быть изменено даже внутри класса
// void changeName(String newName) { this.name = newName; }
}
void main() {
final user = User('u1', 'Alice');
print(user.name); // Alice
}
// 3. Значение вычисляется во время выполнения (в отличие от const)
final DateTime appStartTime = DateTime.now(); // Корректно
// const DateTime appStartTime = DateTime.now(); // Ошибка: значение не известно во время компиляции
// 4. Final с коллекциями и объектами
final List<int> numbers = [1, 2, 3];
// numbers = [4, 5]; // Ошибка: нельзя переприсвоить ссылку
numbers.add(4); // Но можно изменять содержимое mutable-объекта! Теперь список [1, 2, 3, 4]
Важное отличие от const: const создает compile-time константу, значение которой должно быть известно уже на этапе компиляции. final — это run-time константа. Все const переменные неявно являются final, но не наоборот.
// const - известно при компиляции
const double pi = 3.14159;
const List<int> constList = [1, 2, 3]; // Список также иммутабелен
// final - может быть вычислено при выполнении
final double calculatedValue = someComplexCalculation();