Question #189EasyOOP Concepts

What is immutable ? example what is immutable class ?

Answer

Overview

Immutable means an object cannot be changed after it is created. Once you create an immutable object, all its fields stay fixed for its entire lifetime.

The opposite is mutable — an object whose state can be modified after creation.


Mutable vs Immutable

AspectMutableImmutable
State after creationCan changeCannot change
Thread safetyLess safeInherently safe
PredictabilityHarder to reason aboutEasy to reason about
ExamplesRegular class, List
text
const
,
text
final
,
text
@immutable
classes

Mutable Example

dart
class MutablePoint {
  double x;
  double y;

  MutablePoint(this.x, this.y);
}

void main() {
  final p = MutablePoint(1, 2);
  print('${p.x}, ${p.y}'); // 1.0, 2.0

  // ✅ We can change x and y after creation
  p.x = 10;
  p.y = 20;
  print('${p.x}, ${p.y}'); // 10.0, 20.0
}

Immutable Example

dart
class ImmutablePoint {
  final double x; // final → cannot be reassigned
  final double y;

  const ImmutablePoint(this.x, this.y); // const constructor

  // Instead of modifying, return a NEW object
  ImmutablePoint copyWith({double? x, double? y}) {
    return ImmutablePoint(x ?? this.x, y ?? this.y);
  }

  
  String toString() => 'Point($x, $y)';
}

void main() {
  const p = ImmutablePoint(1, 2);
  print(p); // Point(1.0, 2.0)

  // p.x = 10; // ❌ Error! Cannot assign to a final variable.

  // To "change" it, create a new object
  final p2 = p.copyWith(x: 10);
  print(p2); // Point(10.0, 2.0)
  print(p);  // Point(1.0, 2.0) — original unchanged
}

@immutable Annotation in Flutter

Flutter provides the

text
@immutable
annotation from
text
package:meta
to enforce immutability at analysis time:

dart
import 'package:flutter/foundation.dart';


class UserProfile {
  final String name;
  final String email;
  final int age;

  const UserProfile({
    required this.name,
    required this.email,
    required this.age,
  });

  // copyWith pattern — standard in Flutter
  UserProfile copyWith({
    String? name,
    String? email,
    int? age,
  }) {
    return UserProfile(
      name: name ?? this.name,
      email: email ?? this.email,
      age: age ?? this.age,
    );
  }

  
  String toString() => 'UserProfile(name: $name, email: $email, age: $age)';
}

void main() {
  const user = UserProfile(name: 'Alice', email: 'alice@example.com', age: 28);

  // Update — creates a new object
  final updatedUser = user.copyWith(age: 29);

  print(user);        // UserProfile(name: Alice, email: alice@example.com, age: 28)
  print(updatedUser); // UserProfile(name: Alice, email: alice@example.com, age: 29)
}

Note:

text
@immutable
causes the analyzer to warn you if any field is not final — it does not enforce at runtime.


Immutability in Flutter Widgets

All StatelessWidgets in Flutter are immutable by default:

dart
class GreetingCard extends StatelessWidget {
  final String name; // All fields must be final

  const GreetingCard({required this.name, super.key});

  
  Widget build(BuildContext context) {
    return Text('Hello, $name!');
  }
}

This is why Flutter rebuilds widgets instead of modifying them.


text
const
vs
text
final
in Dart

KeywordWhen evaluatedImmutable?
text
final
At runtime✅ Yes (reference is fixed)
text
const
At compile time✅ Yes (value is fixed)
dart
final now = DateTime.now(); // ✅ Set at runtime, cannot be reassigned
const pi = 3.14159;         // ✅ Set at compile time

// const DateTime.now(); // ❌ Error — not a compile-time constant

Benefits of Immutability

  • Thread-safe — no race conditions when multiple isolates share data
  • Predictable — state cannot change unexpectedly
  • Easier debugging — know that an object's state is always the same
  • Flutter performance
    text
    const
    widgets are cached and not rebuilt unnecessarily
  • Pure functions — functions always return the same output for the same input

Flutter Best Practice: Make your data models immutable and use

text
copyWith()
to create modified copies. This works hand-in-hand with state management solutions like BLoC, Riverpod, and Freezed.