This article contains a table and explanation about operator precedence level and associativity in Dart. This also applies for all Dart frameworks including Flutter.
There can be multiple operators in an expression. Dart has some rules to determine which operator should be executed first. In general, operators are executed according to their precedence level and associativity. This article explains how Dart determines the execution order if there are some operators in an expression.
Operator Precedence and Associativity Table
Below is the operator precedence and associativity table of Dart. Operators are executed according to their precedence level. If two operators share an operand, the operator with higher precedence will be executed first. If the operators have the same precedence level, it depends on the associativity. Both the precedence level and associativity can be seen in the table below.
Level  Category  Operator  Associativity 

16  Unary Postfix  expr. expr?. expr++ expr expr1[expr2] expr() 

15  Unary Prefix  expr !expr ++expr expr ~expr await expr 

14  Multiplicative  */ ~/ % 
Lefttoright 
13  Additive  +  
Lefttoright 
12  Shift  << >> >>>> 
Lefttoright 
11  Bitwise AND  & 
Lefttoright 
10  Bitwise XOR  ^ 
Lefttoright 
9  Bitwise OR Postrix   
Lefttoright 
8  Relational and Test Type  < > <= >= as is is! 

7  Equality  == != 

6  Logical AND  && 
Lefttoright 
5  Logical OR   
Lefttoright 
4  If null  expr1 ?? expr2 
Lefttoright 
3  Conditional  expr ? expr1 : expr2 
Righttoleft 
2  Cascade  . . 
Lefttoright 
1  Assignment  = *= /= += = &= ^= <*lt;= >>= ??= ~/=. = %= 
Righttoleft 
Precedence Level
Below is an example of how precedence level determines the order. There are three operators =
, +
, and *
.
int result = (1 + 2) * 3;
print(result); // 9
Because *
has a higher precedence level (14) than +
(13), the *
operator will be executed before +
operator. The =
(assignment) operator has the lowest precedence among them (1), so it will be executed last. Therefore, the expression on the right hand side of the =
operator is equivalent to 1 + (2 * 3)
. First, Dart will execute 2 * 3
, which yields 6
. Then it executes 1 + 6
, which yields 7
. At last, the result is assigned to the result
variable.
Associativity
If there are more than one operators with the same precedence level, Dart will use the associativity of the operator. The table above has a column named associativity. If the associativity is lefttoright the leftmost operator will run first, followed by the next operators from lefttoright. If the associativity is righttoleft the rightmost operator will run first, followed by the next operators from righttoleft.
The example below uses two %
in an expression.
int result = 25 % 3 % 2;
print(result); // 1
Since the associativity of %
is lefttoright, 25 % 3
will be executed first. The result (1
) will be used by the second %
operator which computes 1 % 2
.
The next example contains two =
operators.
int x = 1;
int y = 2;
int z = 3;
x = y = z;
print(x); // 3
print(y); // 3
print(z); // 3
Because the associativity is righttoleft, y = z
will be executed first which means the value of z
(3
) will be assigned to y
. After that, the value of y
(after assigned with the value of z
) will be assigned to x
.
Overriding Precedence
What if you want to override the precedence of two operators. For example, an expression has addition and multiplication operators. By default, the multiplication operator runs first. If you want to run the addition operator first, you can use parentheses.
int result = (1 + 2) * 3;
print(result); // 9
With parentheses, 1 + 2
will be executed first and the result (3
) will be multiplied by 3
afterwards.
Summary
Like other programming languages, Dart also has rules for determining the order of operator executions in an expression. The precedence level is used first. If some operators share the same precedence level, the associativity will be used. You can bookmark this page and refer to the table above when you forget.