Why are certain variables marked as final in flutter custom classes?
Solution 1
Because StatefulWidget
inherits Widget
, which is marked as @immutable
, any subclass of StatefulWidget
must also be immutable (i.e. all fields final).
If you make a StatefulWidget
subclass with non-final fields, it will result in this Dart analysis warning:
info: This class inherits from a class marked as @immutable, and therefore should be immutable (all instance fields must be final). (must_be_immutable at [...] lib....dart:23)
And an explanation of how to use StatefulWidget
from the StatefulWidget documentation:
StatefulWidget instances themselves are immutable and store their mutable state either in separate State objects that are created by the createState method, or in objects to which that State subscribes, for example Stream or ChangeNotifier objects, to which references are stored in final fields on the StatefulWidget itself.
Solution 2
There's no finite answer to this question. This is more of a preference.
Fact is that if a variable can be declared as final
, then why not declare is as so ? final
keyword doesn't hurt your code at all and can potentially help catch bugs.
In fact you can even enable a custom linter rule called prefer_final_locals
which will make compilation fails if you have a non-final variable that is never reassigned.
This allows a double health check : immutable variables won't be able to change. But at the same time, if you forgot to mutate a non-final variable, the compiler will also warn you.
Solution 3
"final" is very similar to "const" in application but different for compile-time reasons: See this link or below for further explanation:
"final" means single-assignment: a final variable or field must have an initializer. Once assigned a value, a final variable's value cannot be changed. final modifies variables.
"const" has a meaning that's a bit more complex and subtle in Dart. const modifies values. You can use it when creating collections, like const [1, 2, 3], and when constructing objects (instead of new) like const Point(2, 3). Here, const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.
Solution 4
With you JavaScript/TypeScript background you was already familiar with the const
keyword. In Java, you don’t have const
, but the equal is final
. When I started working with Dart (for Flutter) I was surprised by both of these two keywords available.
const String personConst = 'Jeroen';
final String personFinal = 'Jeroen';
personConst = 'Bob'; // Not allowed
personFinal = 'Bob'; // Not allowed
In the code above we create a const and a final variable and assign my name to both. You can’t re-assign both of them. But what is the difference?
final
-
A variable with the
final
keyword will be initialized at runtime and can only be assigned for a single time. -
In a class and function, you can define a
final
variable. -
For Flutter specific, when the state is updated, everything in the build method will be initialized again. This includes all the variables with
final
.@override Widget build(BuildContext context) { // your code }
const
- A variable with the
const
keyword is initialized at compile-time and is already assigned when at runtime. - You can’t define
const
inside a class. But you can in a function. - For Flutter specific, everything in the build method won’t be initialized again when the state is updated.
-
const
can’t be changed during runtime.
When to use which keyword?
A simple example for both:
- Use
final
: If you don’t know what it’s value will be at compile-time. For example, when you can need to get data from an API, this happens when running your code. - Use
const
: If you are sure that a value isn’t going to be changed when running your code. For example, when you declare a sentence that always remains the same.
final vs. var
final
vs. var
: When declaring variables, use final
instead of var everywhere you can. This tells Dart that the variable should not be reassigned after initialization. The code analyzer will alert you if any code attempts to set the value again. If a variable's value should not change after it's initialized, Dart's final
keyword can help you avoid bugs related to unexpected mutation.
One problem you may have noticed with using named parameters is that they're optional, and sometimes that is undesirable.
From: https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573
MistyD
Updated on February 08, 2022Comments
-
MistyD over 2 years
I noticed in some of the examples online that classes that extend
StatefulWidget
have instance variables marked with final. Why is that? I understand what the final keyword does. I do not understand why it is being declared with each instance variable that extends the widget class.