Chapter 11 of 12
~12 min read
Extension Functions
Add methods to any class — even ones you don't own, like Java SDK classes or third-party libraries.
The Problem — Java Utility Classes
Java — utility class pattern
// StringUtils.java — helper class
public class StringUtils {
public static String capitalize(String s) {
if (s.isEmpty()) return s;
return Character.toUpperCase(s.charAt(0))
+ s.substring(1);
}
public static boolean isValidEmail(String email) {
return email.contains("@") &&
email.contains(".");
}
}
// Usage — awkward static call
String result = StringUtils.capitalize("hello"); Kotlin — extension function
// Extension on String — feels native!
fun String.capitalize2(): String {
if (isEmpty()) return this
return this[0].uppercaseChar() + substring(1)
}
fun String.isValidEmail() =
contains("@") && contains(".")
// Usage — called like a member function!
val result = "hello".capitalize2()
val valid = "test@email.com".isValidEmail() How it works under the hood
Extension functions are compiled to static utility methods — exactly like your Java utility class. The receiver (this) becomes the first parameter. So "hello".capitalize2() compiles to StringUtils.capitalize2("hello"). No runtime overhead.
Extending Java SDK Classes
Kotlin — extend classes you don't own
// Extend Java's View class
fun View.show() { visibility = View.VISIBLE }
fun View.hide() { visibility = View.GONE }
fun View.invisible() { visibility = View.INVISIBLE }
// Usage — much cleaner than Java!
myButton.show()
myProgressBar.hide()
// Extend Context
fun Context.showToast(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
}
// In Activity (which is a Context):
showToast("Welcome!")Extension Properties
Kotlin
// Extension property on String
val String.wordCount: Int
get() = if (isBlank()) 0 else trim().split(" ").size
"Hello World".wordCount // 2
// Extension property on Int (dp to px)
val Int.dp: Float
get() = this * Resources.getSystem()
.displayMetrics.density
// Usage in Android UI code:
val margin = 16.dp // converts dp to pxNullable Receiver Extensions
Kotlin
// Can even extend nullable types!
fun String?.orDefault(default: String = ""): String {
return this ?: default
}
val name: String? = null
println(name.orDefault("Anonymous")) // Anonymous
println(null.orDefault("Guest")) // Guest Limitations
- Extension functions do NOT modify the actual class — they can't access private members
- If an extension and a member function have the same signature, the member always wins
- Extensions are resolved statically (at compile time), not dynamically like polymorphism