What are Static Members?
Static members belong to the class itself rather than to any specific instance (object). They are shared across all instances of the class. Declare them with the static keyword. Access them using the class name, not an object reference.
Static Fields
class Counter {
// Static field — shared across ALL Counter objects
static int _count = 0;
final int id;
Counter() : id = ++_count;
static int get count => _count;
static void reset() => _count = 0;
}
void main() {
print(Counter.count); // 0
var a = Counter();
var b = Counter();
var c = Counter();
print(Counter.count); // 3
print(a.id); // 1
print(b.id); // 2
Counter.reset();
print(Counter.count); // 0
}
Static Methods
Static methods have no access to this — they cannot reference instance fields or methods. They are utility functions tied logically to the class:
class MathUtils {
// Cannot be instantiated — all static
MathUtils._(); // private constructor
static double square(double x) => x * x;
static double cube(double x) => x * x * x;
static double clamp(double value, double min, double max) =>
value < min ? min : (value > max ? max : value);
static bool isPrime(int n) {
if (n < 2) return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}
}
void main() {
print(MathUtils.square(5)); // 25.0
print(MathUtils.cube(3)); // 27.0
print(MathUtils.clamp(150, 0, 100)); // 100.0
print(MathUtils.isPrime(17)); // true
print(MathUtils.isPrime(15)); // false
}
Static Constants
class Config {
static const String appName = ''CamboFreelance'';
static const String version = ''2.0.0'';
static const int maxRetries = 3;
static const Duration timeout = Duration(seconds: 30);
static const Map<String, String> headers = {
''Content-Type'': ''application/json'',
''Accept'': ''application/json'',
};
}
void main() {
print(Config.appName); // CamboFreelance
print(Config.version); // 2.0.0
print(Config.timeout.inSeconds); // 30
}
Static Factory Methods
A common pattern is static factory methods — named constructors that return instances with validation or special initialization:
class Color {
final int r, g, b;
const Color(this.r, this.g, this.b);
// Static factory methods for named colors
static const Color red = Color(255, 0, 0);
static const Color green = Color(0, 255, 0);
static const Color blue = Color(0, 0, 255);
static const Color white = Color(255, 255, 255);
static const Color black = Color(0, 0, 0);
static Color fromHex(String hex) {
hex = hex.replaceFirst(''#'', '''');
return Color(
int.parse(hex.substring(0, 2), radix: 16),
int.parse(hex.substring(2, 4), radix: 16),
int.parse(hex.substring(4, 6), radix: 16),
);
}
@override
String toString() => ''Color(r=$r, g=$g, b=$b)'';
}
void main() {
print(Color.red); // Color(r=255, g=0, b=0)
print(Color.fromHex(''#1A2B3C'')); // Color(r=26, g=43, b=60)
}
Full Example: Singleton Pattern
class AppLogger {
// Static field holds the single instance
static AppLogger? _instance;
static int _logCount = 0;
// Private constructor
AppLogger._();
// Static getter returns the single instance
static AppLogger get instance {
_instance ??= AppLogger._();
return _instance!;
}
void log(String level, String message) {
_logCount++;
final timestamp = DateTime.now().toIso8601String();
print(''[$timestamp][$level] $message'');
}
void info(String msg) => log(''INFO'', msg);
void error(String msg) => log(''ERROR'', msg);
static int get logCount => _logCount;
}
void main() {
var logger = AppLogger.instance;
logger.info(''App started'');
logger.error(''Something went wrong'');
AppLogger.instance.info(''Same instance'');
print(''Total logs: \$${AppLogger.logCount}'');
}
Output:[timestamp][INFO] App started
[timestamp][ERROR] Something went wrong
[timestamp][INFO] Same instance
Total logs: 3
Exercise
- Create a
StringUtils class with only static methods: capitalize(), isPalindrome(), wordCount(), and reverse().
- Implement a
UserIdGenerator class with a static counter that auto-increments each time a new user ID is requested via a static method nextId().
Quiz
1. How do you access a static method?
- A) Through an instance:
obj.method() - B) Through the class name:
ClassName.method() ✅ - C) Via the super keyword
- D) Using the static keyword at the call site
2. Can a static method access instance fields?
- A) Yes, directly
- B) Yes, via this
- C) No — static methods have no this reference ✅
- D) Only if they are public
3. What keyword makes a class-level constant in Dart?
- A) final
- B) const (but not static)
- C) static const ✅
- D) readonly
Summary
Static members belong to the class, not to instances. Static fields are shared across all objects of the class. Static methods cannot use this and are accessed via the class name. Use static const for compile-time constants. Common patterns include utility classes (all static methods), singleton instances (one shared object), and static factory methods for named constructors.