코틀린의 주요 기능 중 하나는 Null-Safety 이다.
코틀린은 Null-Safety 매커니즘으로 인해 NPE(Null Point Exception)을 찾아보기 힘들다.
Java에서 Exception의 많은 부분을 차지한 NPE은 코틀린의 Null-Safety 를 만나 대부분 제거 되었다.
하지만 Java, C와 같이 Null-Safety 가 지원되지 않는 언어와의 연결에서는 이러한 메커니즘으로 NPE를 완벽하게 보호할 수 없다.
1. 플랫폼 타입
코틀린에서는 Java, C 에서 넘어온 데이터 타입을 특수하게 처리하는데, 이러한 타입을 플랫폼 타입이라고 한다.
플랫폼 타입은 String! 처럼 타입 이름 뒤에 ! 기호를 붙여서 표기한다.
플랫폼 타입: 다른 프로그래밍 언어에서 전달되어 nullable인지 아닌지 알 수 없는 타입
2. 플랫폼 타입 사용 시 발생할 수 있는 문제와 대응
플랫폼 타입의 가장 큰 문제는 null 여부를 판단할 수 없다는 것이다. 따라서 코틀린과 다른 언어를 혼합해서 사용할 땐 NPE를 주의해야 한다.
1) 자바와 코틀린을 함께 사용할 경우 @Nullable, @NotNull 어노테이션을 사용
public class JavaTest{
public String giveName() { ... }
}
위 자바 코드로 반환된 타입을 사용할때에 @Nullable 어노테이션이 붙어 있다면, nullable로 추정하고 String?으로 변경하면 된다.
만약 붙어 있지 않다면 자바에서 모든 것이 nullable일 수 있으므로 최대한 안전하게 접근하기 위해 nullable로 가정하고 접근해야 한다.
!!를 붙이는 경우도 있는데, 이 표현은 not-null을 단정 짓기 위한 표현이다.
[@Nullable @NotNull 어노테이션 사용한 케이스]
// 자바
import org.jetbrains.annotaions.NotNull;
public class UserRepo {
public @NotNull User getUser() {
// ***
}
}
2) 제네릭 타입에서의 문제
자바 API에서 List<User>를 리턴하고 어노테이션은 붙어 있지 않은 경우를 가정해 보자.
코틀린이 디폴트로 모든 타입을 nullable로 다룬다면, 리스트와 리스트 내부의 User 객체들이 null이 아닌 것도 알아야 한다.
리스트 자체만 null인지 확인해서는 충분하지 않고, 내부의 데이터에 대한 null 여부까지 체크해야한다.
*리스트의 경우 map, filterNotNull 등의 메서드로 확인 가능하나 다른 제네릭 타입의 경우 null 체크 과정이 복잡하다.
public class UserRepo {
public List<User> getUsers() {
/// ***
}
}
val users: List<User> = UserRepo().users!!.filterNotNull()
3) 플랫폼 타입은 최대한 제거해서 사용
플랫폼 타입을 사용하는 코드는 해당 부분만 위험 할 뿐 아니라, 활용되는 곳까지 영향을 줄 수 있는 위험한 코드이다.
따라서 이런 코드가 적용된 경우 빨리 제거하는게 좋다.
3. 정리
- 플랫폼 타입: 다른 프로그래밍 언어에서 와서 nullable 여부를 알 수 없는 타입
- 플랫폼 타입은 사용하는 코드 외 활용하는 곳까지 영향을 줄 수 있으므로 가급적 제거하는 것이 좋음
- 혹은 사용하게 되었을때는 nullable 여부를 지정하는 어노테이션을 활용하는 것이 좋음
'Study OR Book > Book' 카테고리의 다른 글
[이펙티브 코틀린] 아이템32: 추상화 규약을 지켜라 (0) | 2025.02.03 |
---|---|
[이펙티브 코틀린] 아이템29: 외부 API를 랩(wrap)해서 사용하라 (0) | 2025.01.21 |
[이펙티브 코틀린] 아이템19: knowledge를 반복하여 사용하지 말라 (0) | 2025.01.15 |
[이펙티브 코틀린] 아이템17: 이름 있는 아규먼트를 사용하라 (0) | 2025.01.08 |
[이펙티브 코틀린] 아이템7: 결과 부족이 발생할 경우 null 또는 Failure를 사용하라 (1) | 2024.12.18 |