Code review in Kotlin: what to check and how to give feedback
\n\nCode review is not just a formality or a way to find bugs. It is a crucial process for knowledge sharing and improving code quality. In Kotlin, with its expressive syntax and powerful features, reviewing requires special attention to detail. In this article, we will break down what to look for when reviewing Kotlin code and how to give feedback that is helpful, not hurtful.
\n\n1. What to check: a checklist for Kotlin developers
\n\nWhen starting a review, don't try to cover everything at once. It's better to go through key categories. Here is a structured checklist for Kotlin.
\n\n1.1. Null Safety and working with nullable types
\nKotlin solves the NPE problem, but only if the developer doesn't overuse !! (not-null assertion). This is a major red flag.
- \n
- What to look for: Use of
!!in production code. It can almost always be replaced with?.let,?:(elvis), or a safe castas?. \n - Example of bad code: \n
fun processUser(user: User?) {\n val name = user!!.name // Potential NPE!\n println(name)\n}\n- \n
- Example of good code: \n
fun processUser(user: User?) {\n user?.let { safeUser ->\n println(safeUser.name)\n } ?: run {\n println("User is null")\n }\n}\n\n1.2. Using collections and Stream API
\nKotlin offers a rich set of functions for working with collections. Check how efficiently and readably they are used.
\n- \n
- What to look for: Unnecessary
forloops wheremap,filter,groupBycould be used. Also, mutable collections (MutableList) if immutable ones (List) would suffice. \n - Example of bad code: \n
val names = mutableListOf<String>()\nfor (item in items) {\n if (item.isActive) {\n names.add(item.name)\n }\n}\n- \n
- Example of good code: \n
val names = items\n .filter { it.isActive }\n .map { it.name } // Immutable list\n\n1.3. Extension functions and scope
\nExtension functions are a powerful tool, but they can easily be "smeared" across the project. Check whether their use is appropriate.
\n- \n
- What to look for: Extension functions that change the state of an object (especially if it's not obvious). Functions that should be class methods but are extracted as extensions for "aesthetics". \n
- Question for the author: "Why is this an extension and not a method of the
Userclass?" \n
1.4. Using when instead of if-else
\nKotlin encourages using when as a more readable alternative to long chains of if-else.
- \n
- What to look for: Ladders of
if-elsewith 3+ conditions. These should be replaced withwhen. \n
// Instead of this:\nif (status == Status.ACTIVE) { ... } else if (status == Status.PENDING) { ... } else { ... }\n\n// Better like this:\nwhen (status) {\n Status.ACTIVE -> { ... }\n Status.PENDING -> { ... }\n else -> { ... }\n}\n\n2. How to give feedback: from criticism to collaboration
\n\nThe technical part is only half the battle. The other half is communication. Bad feedback can demotivate a team. Good feedback can build trust.
\n\n2.1. The "Why, not What" rule
\nInstead of simply saying "This is bad," explain why it's bad and how to fix it.
\n- \n
- Bad: "Here
!!— redo it