Skip to main content
A public field is a member variable declared within a class that is accessible from any library or scope where the class itself is visible. In Dart, visibility is controlled by the identifier name rather than explicit access modifier keywords. Any class member that does not begin with an underscore (_) is implicitly public.

Declaration Syntax

Public fields are declared by specifying an explicit type, var, final, or const followed by the identifier. If var, final, or const are used without an explicit type, the type is inferred from the assigned value.
class Particle {
  // Mutable public field with explicit type
  double x;

  // Mutable public field with type inference
  var y = 0.0; // Inferred as double

  // Immutable public field with type inference
  final created = DateTime.now();

  // Compile-time constant (must be static)
  static const double gravity = 9.81;

  // Constructor using initializing formals
  Particle(this.x);
}

Implicit Accessors

Dart fields are not direct memory access points. When a public field is declared, the compiler implicitly generates accessor methods that define how the field is accessed:
  1. Getter: Generated for all public fields. It returns the value of the field.
  2. Setter: Generated only for non-final (mutable) public fields. It updates the value of the field.
Accessing a field via dot notation (e.g., obj.field) invokes these implicit accessors. This architecture allows a field to be refactored into a custom getter/setter pair without altering the public API contract.

Modifiers and Behavior

The behavior of a public field is determined by the modifiers applied to the declaration:
  • var / Explicit Type: Defines a mutable property. The field can be read and reassigned from any scope.
  • final: Defines a single-assignment property. The field must be initialized exactly once (inline or via the constructor). Once initialized, it is part of the read-only public API.
  • static const: Defines a compile-time constant. Class members declared as const must be explicitly marked static. They are initialized with a compile-time constant value and accessed via the class name.
  • late: Enforces lazy initialization or allows initialization to occur after the constructor body executes. It defers the memory allocation and assignment until the field is first accessed.
  • static: Associates the field with the class itself rather than a specific instance. Static public fields are accessed via the class name (e.g., ClassName.field).

Null Safety Implications

Dart’s sound null safety system enforces strict initialization rules on public fields:
  1. Non-nullable fields: Must be initialized inline, via a constructor’s initializer list, or using an initializing formal (this.field). If immediate initialization is not possible, the late modifier is required.
  2. Nullable fields: Declared with a ? suffix (e.g., String? name). These default to null if not explicitly initialized.

Access Example

void main() {
  // Accessing static const field
  print(Particle.gravity);

  var p = Particle(10.0);

  // Read access (invokes implicit getter)
  print(p.x);

  // Write access (invokes implicit setter)
  // Only valid because 'x' is not final
  p.x = 50.0;
}
Master Dart with Deep Grasping Methodology!Learn More