class Base {
num b;
Base() {
print("in Base");
}
Base.initB(b) {
b = b;
print("in Base.initB");
}
}
class Point extends Base {
num x;
num y;
final num f;
Point(this.x, int y, smth, b): f=smth, super.initB(b) {
print(this.x);
this.y = y;
}
}
main() {
var a = new Point(1, 2, 3, 4);
// output:
// in Base initB
// 1
}
I'm learning Dart but found the documentation obscure. I want to know the initialization order of instance variables. There are two questions:
x, f -> b -> y, is it correct?x and f, which is first?I can understand that the documentation seems obscure. I believe it's completely broken for object initialization, and it's on the "to-fix" list (UPDATE: And that has changed. The specification should now be "more correct" around object initialization.)
In practice, the evaluation order of the initializer list is left-to-right. You can see that by having side-effects in initializer expressions.
The call to the super constructor happens either at the end (in the VM), or at the point where the super-call occurs (in Dart2JS). For that reason, you are recommended to always put the super-call last, and that's likely to be required in a later version of Dart. There is no advantage to putting it earlier.
After all initializer lists have been executed, and all initializing formals (like this.x above) have been processed, the object is considered initialized, and then the constructor bodies are executed in super-class first order with access to the new object as this.
When the actual object field is set is undefined. You only ever see the object after all fields are initialized. It's a perfectly valid implementation strategy to put all the values on the stack when evaluating the initializer lists, then allocate the object just before entering the first constructor body.
Here is an example that shows evaluation order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With