When learning Dart, one common confusion among developers is whether Dart is truly object-oriented — especially when it comes to how values like int behave. At first glance, Dart might appear to treat these values by copy, much like primitive types in Java or C. But is that really the case?
Let’s explore this through examples — and clarify, once and for all, whether Dart is a fully object-oriented language.
Everything in Dart is an Object
First, it’s important to understand:
Dart does not have primitive types like Java or C; all values are objects.
Let’s start with the big truth:
- 5 is an object of type int
- “hello” is an object of type String
- true is an object of type bool
How can we be sure? Let’s test it!
void main() {
print(5.runtimeType); // int
print("hi".runtimeType); // String
print(true.runtimeType); // bool
print(5.isEven); // true
print("hi".toUpperCase()); // HI
print(false.toString()); // false
}
These values have methods and belong to classes.
That’s solid proof they’re objects! Yes, Dart is 100% object-oriented.
Then Why Does This Happen? 🤔
Let’s take a look at a simple Dart example:
void main() {
int x = 5;
int y = x;
int z = y;
print("$x $y $z"); // Output: 5 5 5
x = 100;
print("$x $y $z"); // Output: 100 5 5
}
At first, it looks like x, y, and z are separate copies of the value 5, as if Dart were treating them like raw values instead of objects. But what’s actually happening?
Understanding References and Immutability
In Dart:
- All variables store references to objects, not the objects themselves.
- However, types like int, double, and String are immutable.
- So when you do x = 5, x holds a reference to the int object 5.
When you write:
int y = x;
You’re copying the reference — not the object. But since int is immutable, when you later write x = 100, Dart creates a new int object, and x now points to that. y and z still point to the original 5.
This is similar to how Python behaves with integers:
x = 5
y = x
x = 100
print(x, y) # Output: 100 5
Now Try a Mutable Object
Let’s see what happens with a mutable type like a List:
void main() {
List a = [1, 2];
List b = a;
a[0] = 999;
print("a: $a"); // a: [999, 2]
print("b: $b"); // b: [999, 2]
}
Both a and b reference the same list object, so changing one affects the other — proving that Dart variables are references, just like Python:
a = [1, 2]
b = a
a[0] = 999
print("a:", a) # a: [999, 2]
print("b:", b) # b: [999, 2]
Copying Lists Properly in Dart
If you want to avoid shared references, you can explicitly copy the list:
List b = List.from(a); // or [...a]
This way, changes to a won’t affect b.
Conclusion: Dart Is Fully Object-Oriented
Dart behaves exactly like other object-oriented languages when it comes to object references. The confusion comes from:
- Immutability of basic types like int, double, and String
- The illusion of “copying values” when in fact you’re copying references to immutable objects
So yes, Dart is fully object-oriented — it just has optimization and behavior patterns that make it feel different for simple types.