Is Dart Fully Object-Oriented? Understanding the Truth Through Code

Md. Tariqul Islam

23 June, 2025

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<int> a = [1, 2];
  List<int> 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<int> 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.

Md. Tariqul Islam

23 June, 2025