A generic class is parameterized by a type. Box<T> stores a value of type T and returns the same T from unwrap, with no casts and no dynamic. The same class definition handles many concrete element types.

Program

Play the program to build a Box<String> and a Box<int>, then read both through unwrap.

generic_classes.dart
class Box<T> {
  final T value;
  Box(this.value);
  T unwrap() => value;
}

void main() {
  var name = Box<String>('Ada');
  var age = Box<int>(36);
  var message = '${name.unwrap()} is ${age.unwrap()}';
  print(message);
}
type parameter `class Box<T>` declares a type parameter `T`; each `Box` instance picks a concrete type at construction.
typed field `final T value;` stores exactly the chosen `T`, with no casting or boxing into `Object`.
typed return `T unwrap()` returns the same `T` the caller put in: `Box<String>.unwrap()` is a `String`, `Box<int>.unwrap()` is an `int`.