Skip to main content
Kotlin, despite being a modern and well-designed language, still has common anti-patterns that can lead to bugs, performance issues, and maintenance problems. Here are the most important anti-patterns to avoid when writing Kotlin code.
The !! operator forces a nullable type to be non-null and throws a NullPointerException if the value is null. Use safe calls (?.) and the Elvis operator (?:) instead.
Use data classes for simple data containers to automatically get equals(), hashCode(), toString(), and copy() methods.
Platform types (types coming from Java) may be nullable even if not marked as such. Always handle them carefully.
While extension functions are powerful, overusing them can lead to namespace pollution. Group related functions in utility classes or objects.
Use coroutines for asynchronous operations instead of callbacks or threads for more readable and maintainable code.
Kotlin’s standard library provides many useful functions. Use them instead of reimplementing common functionality.
Use property delegation (lazy, Delegates.observable, etc.) for common property patterns.
Use sealed classes to represent states with associated data instead of using constants or enums.
Use scope functions (let, run, with, apply, also) to make code more concise and readable.
Use inline for higher-order functions to avoid the overhead of lambda object creation and virtual function calls.
Use companion objects for factory methods and static utilities, not for instance-related functionality.
Use type aliases to give meaningful names to complex types, making code more readable and maintainable.
Use extension properties instead of extension functions when the function doesn’t take parameters and returns a value.
For single-method interfaces (SAM interfaces), use lambda expressions instead of object expressions.
Use Kotlin’s collection operations (map, filter, reduce, etc.) for more concise and readable code.
Use destructuring declarations to extract multiple values from objects like pairs, triples, and data classes.
Use string templates ($variable or ${expression}) instead of string concatenation for more readable code.
Use named arguments for better readability, especially when calling functions with many parameters.
Use Kotlin’s Flow for reactive programming instead of callbacks or custom observer patterns.