일단 lateinit 키워드의 의미는 해당 속성의 초기화를 미루겠다는 의미이다. 왜 미루는데? 자바를 기준으로 생각하면 초기화를 미루고 싶으면 일단 생성자에 포함하지 않으면 되자나?
그런데 그렇더라도 초기화가 안되진 않는다. 타입별 초기값으로 자동으로 초기화될 뿐..lateinit 는 아예 이런 초기화도 미룬다는 걸 의미한다.
이런 상황이 왜 필요한지
생각을 해보자. 생성자로 초기화를 강제하진 않지만 포함하고 싶은 속성이 있을 수 있다. 자바의 경우 클래스를 만들 때 아래와 같이 타입만 지정된 속성을 만들면 된다.
String str;
int i;
이 경우 지정된 기본값이나 null 이 할당된 채로 객체가 생성될 것이다. 즉, 객체 생성시 자동으로 초기화가 되기 때문에 클래스를 만들때는 딱히 지정하지 않아도 된다.
하지만 코틀린에서는 객체 생성시 속성을 자동으로 초기화 해주지 않기 때문에 클래스를 만들 때 속성에는 null 이든 뭐든 무조건 초기값을 지정해야 한다. 그렇지 않으면 intellij 기준 아래와 같은 컴파일 에러가 발생한다.
Property must be initialized or be abstract
이 때 lateinit 가 필요하게 된다. lateinit 는 "클래스 생성할 때 초기화는 하지 않지만 사용하기 전에 꼭 하겠다" 라고 컴파일러에 전달해주는 역할을 한다. 때문에 객체를 생성하더라도 초기화를 하지 않은 상태에서 해당 속성을 사용하려고 하면 Exception 이 발생한다.
lateinit 이 활용되는 대표적인 케이스는 상속만을 위한 추상클래스를 만들 때이다. 예를 들어 JPA 에서 @MappedSuperclass 를 만들 때 아래와 같이 활용된다.
@MappedSuperclass
@EntityListeners(value = [AuditingEntityListener::class])
abstract class BaseEntity {
@CreatedDate
@Column(name = "REG_DATE", updatable = false)
lateinit var regDate: LocalDateTime
@LastModifiedDate
@Column(name = "UPDT_DATE")
lateinit var updtDate: LocalDateTime
}
'Backend > Kotlin' 카테고리의 다른 글
[Kotlin] 제네릭(내가 필요한 것만 정리..) (0) | 2021.12.06 |
---|---|
[Kotlin] inline (0) | 2021.12.06 |
[Kotlin] 코틀린에서 유틸함수 만들기 (0) | 2021.11.24 |
[Kotlin] val, const val (0) | 2021.11.22 |
[Kotlin] companion object (0) | 2021.11.22 |