This content originally appeared on DEV Community and was authored by Nyerhovwo Adjekughene
Knowing when to use lazy or lateinit is one of those "aha" moments that separates clean, reliable Kotlin code from spaghetti code - especially in Android development. In this post, I'll break down these powerful property delegates, share my Android use cases, and help you decide which one is right - and when.
🧐 So, what are they?
Both lazy and lateinit are tools that allow delayed initialization of properties - but they solve different problems.
Think of it like this:
🛋️ lazy is like setting up a beanbag you'll only sit on when you feel like it
🔧 lateinit is like screwing on a table leg after you've assembled the frame
Kotlin lazy – For Read-Only, One-Time Initialization
lazy lets you define a read-only property (val) whose value is computed only once - the first time it's accessed.
Real Example: Lazy-loading a Retrofit service
val apiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.build()
.create(ApiService::class.java)
}
Why this works great:
We only initialize the Retrofit service when needed
Saves memory during early startup
Keeps it thread-safe by default (SYNCHRONIZED mode)
🧪 Another Example: Config loading
val config by lazy(LazyThreadSafetyMode.NONE) {
loadRemoteConfig()
}
This disables synchronization for better performance if you guarantee no race conditions (like using it in onCreate() only).
Kotlin lateinit – For Mutable Properties Set Later
lateinit is your tool when you want to declare a non-null var that will be initialized after the object is constructed.
✅ Common in Android:
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
Here, you can't initialize binding at the point of declaration, because layoutInflater isn't ready yet.
⚔️ *lazy vs lateinit *– When to Use Each
Ask Yourself Use Is it a val, and only needs 1 init? lazy Is it a var, assigned after init? lateinit Is it null-safe and side-effect-free? lazy Do you need dependency injection later? lateinit
🧨 Common Mistakes to Avoid
❌ Accessing lateinit before it's initialized
if (::someVar.isInitialized) {
println(someVar)
}
Always check with ::yourVar.isInitialized to avoid UninitializedPropertyAccessException.
Real-world Android Dev Examples
💡 Lazy ViewModel Factory
val viewModelFactory by lazy {
MyCustomViewModelFactory(requireContext())
}
Useful when building custom ViewModels in Fragments or Composables.
lateinit + Dependency Injection (e.g. Dagger/Hilt)
@Inject
lateinit var userRepo: UserRepository
You can't use constructor injection in some Android components (like Fragments), so lateinit is perfect here.
Why This Matters in Real Apps
In one of my projects, using lazy helped me avoid triggering an expensive image loading setup until the user actually opened the gallery screen - reducing cold startup time.
In another case, lateinit saved me from null checks all over a test suite where I needed to inject mocked APIs.
The more your Android app grows, the more these tools help keep code clean, readable, and maintainable.
🧑🏫 Final Advice
🧘 Use lazy when you're dealing with one-time expensive operations
🔧 Use lateinit when you can't initialize immediately but want to avoid nullable types
🤝 Document or comment fields clearly - they might crash if accessed too early!
🤝** Let's Connect**
If you found this article useful or want to ask me about anything from Kotlin to Clean Architecture:
LinkedIn: Here
GitHub: Here (@nerojust)
AndroidDev #Kotlin #Coroutines #MobileDevelopment #ModernAndroid #DevJourney #CleanArchitecture #MVVM
This content originally appeared on DEV Community and was authored by Nyerhovwo Adjekughene

Nyerhovwo Adjekughene | Sciencx (2025-07-14T11:37:58+00:00) Kotlin lazy vs lateinit: When and Why You Should Use Them. Retrieved from https://www.scien.cx/2025/07/14/kotlin-lazy-vs-lateinit-when-and-why-you-should-use-them/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.