Basics
Dynamic and Object
Object is Dart's safe top type: any non-null value fits, but only Object members are callable without a cast. dynamic opts out of static checking, so members and reassignments are accepted at compile time and resolved at runtime.
Program
Play the program to hold a String as Object, do arithmetic on a dynamic int, and print both.
dynamic_object.dart
Replay: real traced execution (multi-file project)
void main() {
Object boxed = 'Ada';
dynamic flexible = 3;
flexible = flexible + 2;
var label = boxed.toString();
print('$label $flexible');
}
boxed ← Ada (as Object)
1void main() {2 Object boxed = 'Ada';3 dynamic flexible = 3;values this stepAda (as Object)boxedflexible ← 3 (dynamic)
2Object boxed = 'Ada';3dynamic flexible = 3;4flexible = flexible + 2;values this step3 (dynamic)flexibleflexible ← 5
3dynamic flexible = 3;4flexible = flexible + 2;5var label = boxed.toString();values this step3 → 5flexiblelabel ← Ada (String)
4flexible = flexible + 2;5var label = boxed.toString();6print('$label $flexible');values this stepAda (String)labelAdaboxedprint('$label $flexible');
5 var label = boxed.toString();6 print('$label $flexible');7}outputAda 5values this stepAdalabel5flexible
Follow the Values
boxedholdsAdaas anObject.flexiblestarts as3usingdynamic.flexiblebecomes5.labelisAdaas aString.- The program prints
Ada 5. | name | visible value | | --- | --- | |boxed| Ada (as Object) | | startingflexible| 3 (dynamic) | | updatedflexible| 5 | |label| Ada (String) | | stdout |Ada 5|
Object top type
`Object boxed = 'Ada'` keeps the value safe; only `Object` members like `toString()` are callable without a cast.
dynamic
`dynamic flexible = 3` skips static checks; `flexible + 2` is resolved at runtime against the underlying `int`.
rebind
A `dynamic` binding can be reassigned to anything; here the value moves from `3` to `5` and stays an `int`.
Exercise: dynamic_object.dart
Reproduce Ada 5, then identify which value changes from 3 to 5.