Theory
Read it cold
Before any teaching, read this Dart and predict its output:
int day = 2;
if (day == 2) {
print('Workshops today');
} else {
print('Regular schedule');
}
You read it perfectly: it prints Workshops today: because Dart's control flow IS your Java, in a lighter jacket. This lesson tours the whole syntax the fast way: skate over the familiar, brake hard at the 4 places Dart differs.
At a glance
Datatypes (brake at rows 3, 6 and 7)
| Type | Holds | Example |
|---|---|---|
| int, double | Whole, decimal numbers | int seats = 350; double fee = 49.5; |
| num | EITHER int or double | num anyNumber = 350; |
| String | Text: capital S, single quotes idiomatic | String fest = 'TechnoUtsav'; |
| bool | true / false | bool open = true; |
| List | Dart's array: growable, indexed from 0 | var events = ['Garba', 'Robo']; |
| Map | Key-value pairs | var seats = {'Garba': 350, 'Robo': 80}; |
| var / dynamic | var INFERS then fixes; dynamic opts out of checking | var day = 2; // an int forever |
Theory
Variables and comments: the accents
var deduces the type from the initializer and fixes it: var seats = 350; makes seats an int; seats = 'full'; later is a compile error. Inference is not looseness.
dynamic is the true opt-out (checking deferred to runtime): rare, deliberate.
final = set once, at runtime (final festName = fetchName();); const = a compile-time constant (const maxSeats = 350;).
Comments: // and /* */ as in Java, plus /// documentation comments that tooling reads: Flutter's libraries are annotated this way.
Practical
Decisions, every loop, and the label trick
void main() {
var events = ['Garba Night', 'Coding Contest', 'Robo Race'];
int day = 2;
// switch: Java-shaped, break per non-empty case
switch (day) {
case 1:
print('Inaugration day');
break;
case 2:
print('Workshops today');
break;
default:
print('Regular schedule');
}
// for-in: the collection walker (new accent)
for (var e in events) {
print(e);
}
// classic for, while, do-while: exactly your Java
for (int i = 0; i < 2; i++) { print('pass $i'); }
// LABEL: break out of BOTH loops in one jump
outer:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (i * j == 4) {
print('found at i=$i, j=$j'); // i=2, j=2
break outer; // exits both loops
}
}
}
}
Quiz
var seats = 350; and 2 lines later: seats = 'Housefull'; What does Dart say?
- Fine: var means the type can change anytime
- Compile error: var inferred int at initialization and the type is fixed forever
- Runtime error when the String is first used as a number
- Fine, but seats becomes dynamic from then on
Show the answer
Compile error: var inferred int at initialization and the type is fixed forever
var is INFERENCE, not permissiveness: the initializer's type (int) becomes the variable's fixed, compiler-checked type, and a String cannot enter: the single most important Dart accent for a Java reader, and this unit's favourite exam question. Option A describes dynamic, the deliberate opt-out you must spell out. Option C postpones an error Dart raises at compile time (static typing's whole point). Option D invents type mutation that no assignment can perform. Rule: var decides once, at birth, by looking.
Think first
Trace the label
In the listing's nested loop, walk i and j by hand: which (i, j) pairs run before the break, what prints, and what would plain break (no label) have done differently?
Show the answer
Pairs in order: (1,1), (1,2), (1,3), (2,1), then (2,2) where ij = 4: prints found at i=2, j=2, and break outer; exits BOTH loops at once. A plain break kills only the INNER loop: the outer would continue with i=3, running (3,1)... until ij hits 4 again... actually (3, anything) gives 3, 6, 9: no more 4s, but the outer loop still runs its course wastefully. Labels exist exactly for this one honest need: escaping nested loops in one jump: Java had them too; Dart keeps them examinable.
Watch out
The 4 accents that catch Java speakers
var is fixed-typed: the quiz; write it on your wrist.
String has a capital S: string does not compile; and single quotes are the house idiom.
List, not arrays: no int[] syntax; events[0] works, .length is a property (no brackets: Java's array .length, not String's .length()).
No standalone char: 'G' is just a 1-character String.
Theory
Skate and brake: the second-language method
You just learned 90% of a language in one lesson because you invested in Java properly: that is transfer, and it is the real syllabus. Keep the accent list where you revise, and practise ONLY the accents: the familiar parts maintain themselves. One language piece remains before Flutter: functions, where Dart hides its best new tricks (arrow bodies, named parameters), next.
Summary
Key takeaways
- Identifiers and comments: Java's rules, plus /// documentation comments.
- Types: int, double, num (either), String (capital S), bool, List (the growable array), Map.
- var infers ONCE from the initializer and fixes the type; dynamic is the rare opt-out; final runtime-once, const compile-time.
- if/else if/else and switch-case: Java-shaped, break per non-empty case.
- Loops: for, for-in for collections, while, do-while; break and continue as known.
- A label (outer:) lets break outer; escape nested loops in one jump: traced at i=2, j=2.
- Memory hook: skate the familiar, brake at var, String, List, for-in.