
lateinit은 나중에 반드시 초기화할 것이라는 보장을 컴파일러에게 알려주는 키워드입니다.
→ 즉, “지금 초기화 못 하지만, 사용되기 전에 꼭 초기화할 거야”라고 선언하는 것.
UninitializedPropertyAccessException 이 발생합니다Android ViewBinding, ViewModel, DI 객체 주입 등 '생성 시점에 초기화 불가능한 non-null 객체'를 다룰 때
private lateinit var binding: FragmentHomeBinding
override fun onCreateView(...) {
binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
binding: FragmentHomeBinding? 로 nullable로 만들고 binding?.textView 같은 null-safe 호출 쓰고 싶지 않기 때문lazy는 해당 프로퍼티가 처음 사용되는 시점에 초기화되는 지연 초기화 기법입니다.
// Adapter 지연 생성
private val adapter by lazy { VideoAdapter() }
// 무거운 객체 지연 생성
private val database by lazy {
Room.databaseBuilder(
context,
AppDatabase::class.java,
"app-database"
).build()
}
이 adapter는 실제로 접근되는 순간에만 생성됩니다.

안드로이드 개발에서는 대부분
이렇게 구분해서 사용합니다.
Kotlin의 lazy는 스레드 안전성을 제어할 수 있는 3가지 실행 모드를 제공합니다.
LazyThreadSafetyMode.SYNCHRONIZED (기본값)멀티 스레드 환경에서 완전히 안전한 기본 모드
synchronized 블록을 사용하여 동시 접근을 제어합니다.성능: 가장 느림(락 비용)
안전성: 멀티스레드 완전 보장
// 기본값 - 명시하지 않으면 SYNCHRONIZED 사용
private val adapter by lazy {
UserAdapter()
}
LazyThreadSafetyMode.PUBLICATION여러 번 초기화될 수 있지만, 최종적으로 하나의 인스턴스만 유지하는 모드
성능: 중간(락 없음)
안전성: 멀티 스레드에서 동일 객체만 보존됨
private val config by lazy(LazyThreadSafetyMode.PUBLICATION) {
AppConfig() // 초기화 시 부작용이 없는 경우
}
LazyThreadSafetyMode.NONE스레드 안전성을 보장하지 않는 가장 빠른 모드
성능: 가장 빠름
안전성: UI thread에서 사용 시 문제 없음
// UI 스레드에서만 접근하는 경우
private val adapter by lazy(LazyThreadSafetyMode.NONE) {
UserAdapter()
}
class MyFragment : Fragment() {
private lateinit var binding: FragmentMyBinding
override fun onCreateView(...) : View? {
binding = FragmentMyBinding.inflate(inflater, container, false)
return binding.root
}
}
onDestroyView()가 호출되면 View는 사라지지만 binding 변수는 Fragment가 메모리에서 사라질 때까지 계속 View를 참조하고 있습니다.
IllegalStateException 발생 가능성이 있습니다.private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(...) : View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
_binding = null
}
nullable + onDestroyView에서 null 처리binding 접근 시점도 강제됩니다.