lateinit은 2가지 경우에 사용하고 있었다.
- 전역변수인데 nullable을 허용하면 null 처리를 해줘야 하는 불편함.
- hilt를 통해 components(activiry, fragment..)에 주입이 필요할 경우.
lateinit 단어만 봐도 나중에 초기화 하겠다. (그러니 non-null로 선언하게 해줘. null 처리 하기 싫음.)
위 이유가 맞는것 같기도 하고..
- 보통 생성자에서 속성을 초기화 하지만 이게 때론 불편할 때가 있다.
- di나 test 에서 초기화 하는데 사용하기도 함.
- 1)최상단(전역 변수), 2)클래스 안, 3)로컬 변수(private?) 로 선언
- isInitialized로 초기화 되어있는지 확인 가능.
https://kotlinlang.org/docs/properties.html#late-initialized-properties-and-variables
Properties | Kotlin
kotlinlang.org
보통 생성자에서 속성을 초기화.
이게 때론 불편함. di를 통해 초기화 하기도 하고,
유닛 테스트의 설정 함수에서 초기화 하기도 함.
이런 상황을 위해, lateinit을 설정한다.
public class OrderServiceTest {
lateinit var orderService: OrderService
@SetUp fun setup() {
orderService = OrderService()
}
@Test fun processesOrderSuccessfully() {
// Calls orderService directly without checking for null
// or initialization
orderService.processOrder()
}
}
lateinit modifier은 var 에 다음에 선언하여 사용 가능.
- 최상단에 선언
- 로컬 변수
- 클래스의 바디 안
클래스 속성을 위해선
- primary 생성자에 선언하지 않는다.
- custom getter setter을 하지 않는다.
non-nullable 여야 하며, primitive 타입일 수 없다.
초기화 전에 접근한다면 exception 발생.
class ReportGenerator {
lateinit var report: String
fun printReport() {
// Throws an exception as it's accessed before
// initialization
println(report)
}
}
fun main() {
val generator = ReportGenerator()
generator.printReport()
// Exception in thread "main" kotlin.UninitializedPropertyAccessException: lateinit property report has not been initialized
}
isInitialized로 초기화 되어있는지 확인 가능.
class WeatherStation {
lateinit var latestReading: String
fun printReading() {
// Checks whether the property is initialized
if (this::latestReading.isInitialized) {
println("Latest reading: $latestReading")
} else {
println("No reading available")
}
}
}
fun main() {
val station = WeatherStation()
station.printReading()
// No reading available
station.latestReading = "22°C, sunny"
station.printReading()
// Latest reading: 22°C, sunny
}
isInitialized는 이미 접근이 가능할 때만 사용할 수 있다.
동일 클래스 안, outer class 또는 같은 파일의 최상단에서 선언해야 한다.