On this page27 sections
- Prerequisites
- Connection With Previous Lectures
- Learning Objectives
- 1. Values That Should Never Change
- 2. Declaring a final Variable
- 3. A final Variable Cannot Be Reassigned
- 4. final With an Explicit Type
- 5. A final Variable Can Hold a Calculated Value
- 6. Declare a final Now, Assign It Once Later
- 7. What Is const?
- 8. const Needs a Value Known Before the Program Runs
- 9. final vs const
- 10. Constants at the Top Level
- 11. late — Declare Now, Assign Before Use
- 12. Breaking the Promise
- 13. late final — Assign Once, Later
- 14. Choosing the Right Keyword
- 15. A Real-World Example
- Code Examples
- Common Beginner Mistakes
- Best Practices
- Mini Challenge
- Practice Questions
- Practice Answers
- Quick Revision
- Key Takeaways
- What's Next?
Lecture 06 — final, const & late
| Category | 2 — Variables & Data Types |
| Lecture | 006 of 140 |
| Estimated video length | 12 min |
| Target | Dart 3.12.2 |
| Level | Beginner |
Every variable so far could be changed by any line of the program.
finalandconstlock a value in place, andlatelets you promise a value that arrives a little later.
Contents
Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways
Every error message in this lecture is real. Each one was produced by running the code shown on Dart 3.12.2, so you will recognize it when you meet it yourself.
Prerequisites
Students should already understand, from Lectures 001–005:
main(),print(), and string interpolation with$- declaring, initializing, and assigning variables
- the types
String,int,double, andbool - why a top-level variable must get its value where it is declared (Lecture 004)
- declaring variables with
varand how Dart infers their type (Lecture 005)
Connection With Previous Lectures
In Lecture 005, var worked out each variable's type for us. But a var variable can still
be given a new value by any line of the program:
void main() {
var taxRate = 0.17;
taxRate = 0.5; // a typo, or a mistake — Dart allows it
print(taxRate);
}0.5Nothing stopped that second line. Yet many values should never change once they are set: a tax rate, a student's name on a report, the number of days in a week. We need a way to tell Dart "this value is fixed" — and have Dart refuse any line that tries to change it.
Learning Objectives
By the end of this lecture you will be able to:
- Explain why some values should never change
- Declare variables with
finalandconst - Assign a
finalvariable exactly once, even after its declaration - Explain the difference between
finalandconst - Recognize which values can be
constand which can only befinal - Use
lateto declare a top-level variable whose value arrives later - Choose between
var,final,const, andlate - Recognize the error messages Dart produces for common mistakes with these keywords
1. Values That Should Never Change
A normal variable can be changed as often as you like. A final or constant variable is given its value once, and then that value stays the same for the rest of the program.
Analogy — a normal variable is a note written in pencil: you can erase it and write something new. A
finalorconstvariable is written in ink: once it is on the page, it stays.
Dart has two keywords for values written in ink: final and const.
2. Declaring a final Variable
Write final in place of var:
void main() {
final name = 'Ali';
final age = 20;
print(name);
print(age);
}Ali
20Like var, final infers the type from the value: name is a String, age an int.
3. A final Variable Cannot Be Reassigned
Try to give a final variable a new value, and the program does not compile:
void main() {
final name = 'Ali';
name = 'Sara';
print(name);
}Error: Can't assign to the final variable 'name'.
name = 'Sara';
^^^^Dart catches this before the program runs. The accidental tax-rate change from the Connection section is now impossible.
4. final With an Explicit Type
You can write the type after final:
void main() {
final String city = 'Lahore';
final double balance = 1000;
print(city);
print(balance);
}Lahore
1000.0As in Lecture 004, 1000 in a double is stored as 1000.0. Write final alone or
final plus a type — never final var.
5. A final Variable Can Hold a Calculated Value
The value of a final variable does not have to be typed out. It can be the result of a
calculation that uses other variables:
void main() {
var price = 250;
var quantity = 4;
final total = price * quantity;
print('Total: $total');
}Total: 1000The calculation happens while the program runs, and its result is locked into total.
6. Declare a final Now, Assign It Once Later
Inside a function, a final variable may be declared first and assigned later — exactly
once:
void main() {
final String grade;
grade = 'A';
print(grade);
}AAssigning it a second time is an error:
void main() {
final String grade;
grade = 'A';
grade = 'B';
print(grade);
}Error: Final variable 'grade' might already be assigned at this point.
grade = 'B';
^^^^^And, just like the variables in Lecture 004, it cannot be read before it has a value:
void main() {
final String grade;
print(grade);
}Error: Final variable 'grade' must be assigned before it can be used.
print(grade);
^^^^^7. What Is const?
const also creates a variable that never changes. Write it the same way as final:
void main() {
const daysInWeek = 7;
const taxRate = 0.17;
print(daysInWeek);
print(taxRate);
}7
0.17Changing a const is rejected in the same way:
void main() {
const taxRate = 0.17;
taxRate = 0.2;
print(taxRate);
}Error: Can't assign to the const variable 'taxRate'.
taxRate = 0.2;
^^^^^^^8. const Needs a Value Known Before the Program Runs
A const value must be known when the program is compiled — before it starts running.
That is why it is called a compile-time constant. Literal values and calculations made only
from literals and other constants are fine:
void main() {
const minutesPerHour = 60;
const secondsPerDay = 24 * minutesPerHour * 60;
print(secondsPerDay);
}86400But a value that comes from a normal variable is only known while the program runs, so it
cannot be const:
void main() {
var price = 100;
const total = price * 3;
print(total);
}Error: Not a constant expression.
const total = price * 3;
^^^^^Surprisingly, the same error appears if price is final: final means "set once", not
"known before the program runs". The fix is to make total a final variable, as in
section 5 — or to make price a const too.
9. final vs const
final | const | |
|---|---|---|
| Can be reassigned? | No | No |
| Value decided | while the program runs | before the program runs |
| Can use normal variables? | Yes | No — only literals and other constants |
| Can be assigned after declaration? | Yes, once (inside a function) | No — value on the same line |
| Example | final total = price * quantity; | const daysInWeek = 7; |
A simple way to remember it: every const is fixed, but not every fixed value can be a
const. If you know the value while writing the code — 7 days, a 0.17 tax rate — use
const. If the value has to be worked out first, use final.
const has more uses with lists and objects; we will meet them in Lecture 046 — Collection
Features and Lecture 055 — Named & Constant Constructors.
10. Constants at the Top Level
final and const both work outside main(). As with every top-level variable, they must
get their value right where they are declared:
const appName = 'Dart Course';
const maxScore = 100;
void main() {
print(appName);
print('Maximum score: $maxScore');
}Dart Course
Maximum score: 100Notice the names. Some languages write constants in capitals, like MAX_SCORE. Dart's style
guide uses lowerCamelCase for constants too: maxScore, appName, taxRate.
11. late — Declare Now, Assign Before Use
Lecture 004 showed that a top-level String name; without a value is an error. Sometimes,
though, the value really is not available yet when you declare the variable. The late
keyword tells Dart: "I promise to assign this before anyone reads it."
late String userName;
void main() {
userName = 'Sara';
print('Welcome, $userName');
}Welcome, SaraWithout late, the first line would be the error from Lecture 004. With late, Dart accepts
the declaration and trusts your promise.
Why Dart needs this promise in the first place is part of null safety, which we study in
Lectures 012–016. For now, read late as "the value comes later".
12. Breaking the Promise
Dart cannot always check a late promise before the program runs. If you read the variable
before assigning it, the program compiles, starts, and then stops with an error:
late String userName;
void main() {
print(userName);
}Unhandled exception:
LateInitializationError: Field 'userName' has not been initialized.This is the first error in this course that happens while the program is running. Dart
also prints several lines showing where it stopped; they are left out here. We will learn to
read them in Category 14 — Error & Exception Handling. Use late only when you are sure the
assignment happens first.
13. late final — Assign Once, Later
late and final can be combined. The result is a variable that gets its value later, and
then never changes:
late final String studentId;
void main() {
studentId = 'STU-104';
print('ID: $studentId');
}ID: STU-104A second assignment is caught while the program runs:
late final String studentId;
void main() {
studentId = 'STU-104';
studentId = 'STU-200';
print(studentId);
}Unhandled exception:
LateInitializationError: Field 'studentId' has already been initialized.late has one more use — delaying a calculation until the value is first needed — which
makes sense once we have functions (Lecture 030) and classes (Lecture 053).
14. Choosing the Right Keyword
Start from the strictest keyword and loosen only when you must:
const— the value is known while writing the code:const daysInWeek = 7;final— the value is set once but worked out while running:final total = price * quantity;var— the value really needs to change:var balance = 1000.0;late— only when a variable cannot get its value where it is declared.
Most variables in real Dart code are final; a var signals a value that is meant to
change.
15. A Real-World Example
const shopName = 'Corner Books';
const taxRate = 0.1;
late final String cashier;
void main() {
cashier = 'Zayan';
final book = 'Dart Basics';
final price = 800;
final quantity = 2;
final subtotal = price * quantity;
final tax = subtotal * taxRate;
final total = subtotal + tax;
var loyaltyPoints = 50;
loyaltyPoints = loyaltyPoints + 16;
print('$shopName — cashier: $cashier');
print('$book x $quantity');
print('Subtotal: $subtotal');
print('Tax: $tax');
print('Total: $total');
print('Loyalty points: $loyaltyPoints');
}Corner Books — cashier: Zayan
Dart Basics x 2
Subtotal: 1600
Tax: 160.0
Total: 1760.0
Loyalty points: 66Each keyword has a job: the shop name and tax rate are known in advance (const), the cashier
is set once in main() (late final), the receipt values are calculated once (final), and
only the loyalty points change (var).
Code Examples
Example 1 — Basic final
void main() {
final name = 'Ali';
final age = 20;
print('Name: $name');
print('Age: $age');
}Name: Ali
Age: 20Example 2 — final With Explicit Types
void main() {
final String name = 'Sara';
final int age = 18;
final double height = 5.6;
final bool isStudent = true;
print('$name, $age, $height, $isStudent');
}Sara, 18, 5.6, trueExample 3 — final Assigned Once, Later
void main() {
final String result;
result = 'Passed';
print('Result: $result');
}Result: PassedExample 4 — Basic const
void main() {
const hoursInDay = 24;
const pi = 3.14159;
const greeting = 'Hello';
print(hoursInDay);
print(pi);
print(greeting);
}24
3.14159
HelloExample 5 — const From Other Constants
void main() {
const daysInWeek = 7;
const hoursInDay = 24;
const hoursInWeek = daysInWeek * hoursInDay;
print('Hours in a week: $hoursInWeek');
}Hours in a week: 168Example 6 — late at the Top Level
late String language;
void main() {
language = 'Dart';
print('Learning $language');
}Learning DartExample 7 — Student Marks
const totalMarks = 300;
void main() {
final student = 'Ali';
final math = 80;
final science = 75;
final english = 85;
final obtained = math + science + english;
final percentage = obtained / totalMarks * 100;
print('Student: $student');
print('Obtained: $obtained / $totalMarks');
print('Percentage: $percentage');
}Student: Ali
Obtained: 240 / 300
Percentage: 80.0How it works
totalMarksis the same for every student and known in advance: a top-levelconst.- The marks and
obtainedare set once:final. - Division with
/gives adouble, sopercentageprints as80.0.
Example 8 — Shopping Total
const deliveryFee = 150;
void main() {
final product = 'Notebook';
final price = 500;
var quantity = 2;
quantity = quantity + 1;
final total = price * quantity + deliveryFee;
print('Product: $product');
print('Quantity: $quantity');
print('Total: $total');
}Product: Notebook
Quantity: 3
Total: 1650How it works
- The delivery fee is a fixed rule of the shop:
const. - The customer changes their mind about the quantity, so
quantitymust bevar. totalis calculated once, after the quantity is settled:500 * 3 + 150is1650.
Example 9 — Bank Balance
const minimumBalance = 500.0;
late final String accountHolder;
void main() {
accountHolder = 'Sara';
var balance = 2000.0;
balance = balance - 1200;
final spendable = balance - minimumBalance;
print('Account: $accountHolder');
print('Balance: $balance');
print('Spendable: $spendable');
}Account: Sara
Balance: 800.0
Spendable: 300.0How it works
minimumBalanceis a bank rule known in advance, so it isconst.accountHolderis assigned once insidemain(), then never changes:late final.balancechanges after a withdrawal, so it isvar.spendableis worked out once from the current balance:800.0 - 500.0is300.0.
Example 10 — Temperature Conversion
const freezingPoint = 32;
void main() {
final celsius = 25.0;
final fahrenheit = celsius * 9 / 5 + freezingPoint;
print('Celsius: $celsius');
print('Fahrenheit: $fahrenheit');
}Celsius: 25.0
Fahrenheit: 77.0How it works
- Water always freezes at
32°F, sofreezingPointisconst. celsiusisfinal, sofahrenheit, calculated from it, can only befinaltoo.
Common Beginner Mistakes
1. Trying to change a final variable
void main() {
final name = 'Ali';
// name = 'Sara'; // ✗
}Error: Can't assign to the final variable 'name'.If the value genuinely needs to change, use var instead.
2. Assigning a final variable twice
void main() {
final String grade;
grade = 'A';
// grade = 'B'; // ✗
}Error: Final variable 'grade' might already be assigned at this point.A final variable may be assigned after its declaration, but only once.
3. Making a const from a variable
void main() {
final price = 100;
// const total = price * 3; // ✗
}Error: Not a constant expression.const values must be known before the program runs. Use final total = price * 3;.
4. Declaring a const without a value
void main() {
// const int maxScore; // ✗
}Error: The const variable 'maxScore' must be initialized.
Try adding an initializer ('= expression') to the declaration.A const gets its value on the same line, always.
5. Writing final and var together
void main() {
// final var name = 'Ali'; // ✗
}Error: Members can't be declared to be both 'final' and 'var'.
Try removing the keyword 'var'.final already replaces var. Write final name = 'Ali'; or final String name = 'Ali';.
6. Reading a late variable before assigning it
late String userName;
void main() {
// print(userName); // ✗ before any assignment
}LateInitializationError: Field 'userName' has not been initialized.This one compiles and crashes while running. Assign first, read second.
7. Writing constants in capitals
MAX_SCORE compiles, but it is not Dart style. Write maxScore.
Best Practices
- Prefer
constwhen the value is known while writing the code. - Use
finalfor any value that is set once — this covers most variables. - Use
varonly when the value really needs to change. - Give
finalandconstvariables their value on the declaration line whenever you can. - Use
latesparingly, and assign it as early as possible. - Name constants in lowerCamelCase:
taxRate, notTAX_RATE.
Mini Challenge
Write a program for Zayan's class test. The maximum mark is 50 and the pass mark is 20 —
both known in advance. Zayan scores 38. Calculate how many marks he scored above the pass
mark. Use const and final only — no var.
Your program should print exactly:
Student: Zayan
Score: 38 / 50
Above pass mark by: 18Try it yourself before opening the solution.
Show solution
const maxMarks = 50;
const passMark = 20;
void main() {
final student = 'Zayan';
final score = 38;
final aboveBy = score - passMark;
print('Student: $student');
print('Score: $score / $maxMarks');
print('Above pass mark by: $aboveBy');
}Student: Zayan
Score: 38 / 50
Above pass mark by: 18How it works
maxMarksandpassMarkare rules of the test, known in advance:const.student,score, and the calculatedaboveBy(38 - 20) are set once:final.
Practice Questions
Work through these in order — they run from beginner to application to challenge. Every question gives you exact values, so you can compare your output with the answers.
Beginner
- Use
finalto store the city'Karachi'and print it. - Use
constto storemonthsInYear = 12and print it. - Use
finalwith explicit types to storename = 'Sara'(String) andbalance = 1500(double). Print both, each on its own line.
Application
-
Store
price = 450andquantity = 2withfinal, calculate the total withfinal, and printTotal: 900. -
Use
constto storeminutesPerHour = 60andhoursPerDay = 24, then calculateminutesPerDayas aconstand print it. -
This program does not compile. Change one word so that it prints
Total: 600:void main() { var price = 200; const total = price * 3; print('Total: $total'); } -
Declare
final String result;insidemain(), assign it'Pass'on the next line, and printResult: Pass. -
Declare a top-level
late String teacher;. Inmain(), assign'Mr. Ahmed'and printTeacher: Mr. Ahmed.
Challenge
- Ali's savings start at
1000. He adds250, then adds100. The bank pays a fixed bonus of50, known in advance. Choosevar,final, orconstfor each value, and printSavings: 1350andWith bonus: 1400. - A temperature program stores the freezing point
0and boiling point100of water in Celsius. Store today's temperature36.6, then calculate how far it is from boiling. PrintBelow boiling by: 63.4. Explain in one sentence why the distance cannot be aconst.
Practice Answers
Question 1 — Solution
void main() {
final city = 'Karachi';
print(city);
}KarachiQuestion 2 — Solution
void main() {
const monthsInYear = 12;
print(monthsInYear);
}12Question 3 — Solution
void main() {
final String name = 'Sara';
final double balance = 1500;
print(name);
print(balance);
}Sara
1500.01500 is stored in a double, so it prints as 1500.0.
Question 4 — Solution
void main() {
final price = 450;
final quantity = 2;
final total = price * quantity;
print('Total: $total');
}Total: 900Question 5 — Solution
void main() {
const minutesPerHour = 60;
const hoursPerDay = 24;
const minutesPerDay = minutesPerHour * hoursPerDay;
print(minutesPerDay);
}1440minutesPerDay is built only from constants, so it can be const too.
Question 6 — Solution
Change const to final, because total uses the normal variable price:
void main() {
var price = 200;
final total = price * 3;
print('Total: $total');
}Total: 600Question 7 — Solution
void main() {
final String result;
result = 'Pass';
print('Result: $result');
}Result: PassQuestion 8 — Solution
late String teacher;
void main() {
teacher = 'Mr. Ahmed';
print('Teacher: $teacher');
}Teacher: Mr. AhmedQuestion 9 — Solution
const bonus = 50;
void main() {
var savings = 1000;
savings = savings + 250;
savings = savings + 100;
final withBonus = savings + bonus;
print('Savings: $savings');
print('With bonus: $withBonus');
}Savings: 1350
With bonus: 1400Question 10 — Solution
const freezingPoint = 0;
const boilingPoint = 100;
void main() {
final today = 36.6;
final belowBoiling = boilingPoint - today;
print('Freezing point: $freezingPoint');
print('Below boiling by: $belowBoiling');
}Freezing point: 0
Below boiling by: 63.4The distance uses today, a final variable, and a const may use only values known
before the program runs.
Quick Revision
- What is the difference between a
varvariable and afinalvariable? - Can a
finalvariable be declared on one line and assigned on a later line? - When is a
constvalue decided? - Why can
const total = price * 3;fail even whenpriceisfinal? - What naming style does Dart use for constants?
- What does
latepromise? - When does a broken
latepromise cause an error — before or while the program runs? - Which keyword should you reach for first:
const,final, orvar?
Key Takeaways
finalandconstcreate variables that cannot be reassigned.finalis set once; its value can be worked out while the program runs.- A
finalvariable inside a function may be assigned after its declaration — exactly once. constis a compile-time constant: its value must be known before the program runs.- A
constcan use only literals and other constants — notvarorfinalvariables. - Constants use lowerCamelCase names, like every other variable.
latelets you declare a variable now and assign it before it is read; reading it too early stops the running program with aLateInitializationError.- Prefer
const, thenfinal, thenvar; uselateonly when you must.
What's Next?
Lecture 07 — Dart Data Types. We have been using String, int, double, and bool
since Lecture 004. Next we look at Dart's data types properly: what each type can store, how
they relate to each other, and which other types Dart offers beyond these four.