둘다 초기화를 나중에 한다는 공통점이 있지만, 구체적인 쓰임이 다르다.
| lateinit | by lazy |
|---|---|
| var 재할당 가능 | val 재할당 불가능 |
| 개발자가 직접 초기화 | 접근시 자동으로 초기화 |
class MainActivity : ComponentActivity() {
private lateinit var analytics: AnalyticsLogger
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
analytics = AnalyticsLogger(this)
setContent {
HomeScreen(
onClick = {
analytics.log("home_button_click")
}
)
}
}
}
onCreate 함수 안에서 직접 초기화 한다
그렇게 하는 이유는 선언 시점에는 context가 없기 때문에, activity가 onCreate 되고 나서 ActivityContext(this)를 넣기 위함이다.
lateinit 변수를 초기화 전에 가져다 쓰게 되면 UninitializedPropertyAccessException가 발생한다
class MainActivity : ComponentActivity() {
private val menuItems by lazy {
listOf(
"홈",
"리뷰",
"마이페이지"
)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HomeScreen(menuItems = menuItems)
}
}
}
해당 변수가 미리 만들어지는 것이 아니라 처음 접근할 때에 만들어진다.
val이기 때문에 한 번 만들어지고 재할당은 안된다
@Composable
fun HomeScreen() {
val tabs = remember {
listOf("전체", "진행중", "완료")
}
TabRow(selectedTabIndex = 0) {
tabs.forEach { title ->
Tab(
selected = title == "전체",
onClick = {},
text = { Text(title) }
)
}
}
}
compose에서는 remember로도 사용한다.