What are Metadata (Annotations)?
Metadata (also called annotations) are used to provide additional information about your code. They are denoted by the @ symbol followed by an identifier. Annotations can be attached to libraries, classes, methods, fields, parameters, and more. Dart comes with several built‑in annotations, and you can also define your own. Annotations are often used by tools (like the Dart analyzer, documentation generators, and code generation packages) to provide extra behavior or information.
Built‑in Annotations
Dart provides a few built‑in annotations that are recognized by the analyzer and the compiler:
@override
@overrideIndicates that a method overrides a method from a superclass. If the superclass method does not exist, the analyzer will report an error. This helps catch typos or mismatched signatures.
@deprecated
@deprecatedMarks a library element as deprecated (discouraged). The analyzer will show a warning when the element is used. You can optionally provide a message explaining the deprecation and suggesting alternatives.
@required (from meta package)
@required (from meta package)Indicates that a named parameter is required. The analyzer will warn if the parameter is omitted. This is commonly used in Flutter constructors. It is not built‑in; you must import package:meta/meta.dart.
@immutable (from meta package)
@immutable (from meta package)Indicates that a class is immutable (all fields are final). The analyzer will warn if the class has non‑final fields.
@protected (from meta package)
@protected (from meta package)Indicates that a member should be used only within its own library or by subclasses. The analyzer will warn if accessed from outside.
Creating Custom Annotations
You can define your own annotations by creating a class whose constructors can be invoked with const. The class name (or a constant of that type) becomes the annotation.
Using Annotations with Code Generation
Custom annotations are most powerful when used with code generation tools like build_runner and packages such as json_serializable, freezed, or riverpod. These packages read annotations at build time and generate code based on them. For example, json_serializable uses @JsonSerializable to generate fromJson and toJson methods.
Accessing Annotations at Runtime (Mirrors)
Dart’s dart:mirrors library allows you to inspect annotations at runtime. However, mirrors are not available on all platforms (e.g., Flutter web), and they can increase code size. For most cases, compile‑time code generation is preferred over runtime reflection.
Key Takeaways
- Annotations (metadata) are attached to code elements using
@.
- Annotations (metadata) are attached to code elements using
- Built‑in annotations include
@override,@deprecated, and@required(from meta).
- Built‑in annotations include
- Custom annotations are defined as
constclasses.
- Custom annotations are defined as
- Annotations are widely used for code generation (e.g.,
json_serializable).
- Annotations are widely used for code generation (e.g.,
- Use
dart:mirrorsfor runtime inspection, but prefer compile‑time generation.
- Use