lateinit
과 by lazy
의 차이에 대해 정리하던 중 문득 왜 lateinit에는 자바 primitve Type을 사용할 수 없는지 궁금해졌다.
일단 lateinit
이 non-null 프로퍼티로만 사용가능한 이유부터 살펴봐야한다.
lateinit
을 사용한다는 것은 지금 바로 초기화하지 않았지만 언젠가는 값을 할당할거야! 라고 약속해 놓는 것이다.
nullable 변수로 해놓으면 매번 null-safe한 작업을 해줘야하니 귀찮잖아요~
그리고 그것을 사용했을 때, 해당 변수의 초기화 여부를 null로 판단한다. (그것도 매번 접근할 때마다 확인한다고 하네요)
null
일 경우, 런타임에 예외를 던진다.
이 말은, 우리가 lateinit
변수에 타입에 맞는 어떤 값이든 넣을 수 있지만 null
은 넣을 수 없다는 말이다.
val nonNullable: Int = 10
val nullable: Int? = null
위의 두 변수를 컴파일해서 java로 보게 되면
final int nonNullable;
final java.lang.Integer nullable;
...
이렇게 변하게 된다. non-Nullable한 int
는 그대로 java의 int
가 되었지만 nullable한 int
는 Integer
가 된다.
이렇듯 우리는 null
을 java primitive type에 넣을 수 없다.
private lateinit var x: Int
과 같이 사용한다고 했을 경우를 살펴보자.
위의 코드를 컴파일하면 x
는 int
타입으로 컴파일되어야 한다. 하지만 lateinit
변수이기 때문에 null
을 사용하여 초기화여부를 판단하게 된다. 하지만 java int 타입(혹은 primitive type)에는 null을 넣을 수 없다!
그러니 다음과 같이 수정해보자. private lateinit var x: Int?
이렇게 lateinit
변수가 null
값을 가질 수 있게 된다면 해당 변수가 초기화 되었는지 안되었는지 확인할 수 없다. 따라서 nullable type을 사용할 수 없다.
게다가 lateinit
이라는 타입 자체가 null
타입을 피하기 위해 만들어졌기 때문에 lateinit
에 nullable type을 사용하게 된다면 lateinit의 목적성을 어기게 된다.
따라서!! 우리는 lateinit
변수에 int
, boolean
같은 java primitive type이나 nullable type을 사용할 수 없다!
https://www.baeldung.com/kotlin/lateinit-primitive-types
https://8iggy.tistory.com/257
이미지 출처 : https://www.geeksforgeeks.org/data-types-in-java/