밤빵's 개발일지
[TIL]20241007 Safe Call(?.), Elvis 연산자(?:), Not-null Assertion(!!) 활용 본문
코틀린에서 제공하는 대표적인 null 처리 방법으로 Safe Call(?.), Elvis 연산자(?:), 그리고 Not-null Assertion(!!)이 있다. 오늘 개발일지에서는 이 세 가지 null 처리 방법의 구체적인 예시와 함께 차이점을 어제 작성한 개발일지 내용보다 조금 더 자세하게 정리해봤다.
▶Safe Call 연산자(?.)
Safe Call 연산자 '?.'는 null일 가능성이 있는 객체에서 메서드나 프로퍼티에 접근할 때 사용하는 연산자이다. 객체가 null이 아니면 해당 메서드를 호출하거나 프로퍼티에 접근하고, 객체가 null이면 그냥 null을 반환한다. 이를 통해 null 체크를 간단하게 할 수 있다.
var name: String? = "Kotlin"
val length = name?.length // name이 null이 아니면 length 호출, null이면 null 반환
println(length) // 출력: 6
→ name 변수는 Nullable 타입(String?)이기 때문에 null을 가질 수 있다. Safe Call 연산자를 사용하면 name이 null인지 확인한 뒤에 메서드를 호출하기 때문에 NullPointerException을 방지할 수 있다. 만약 name이 null이라면 name?.length는 null을 반환하고, 그렇지 않으면 length() 메서드가 호출되어 문자열의 길이를 반환한다.
▷Safe Call 연산자 장점
- 코드가 간결해진다. 여러 줄에 걸친 null 체크를 한 줄로 처리할 수 있다.
- null일 가능성이 있는 객체에 안전하게 접근할 수 있다.
- NPE를 사전에 방지할 수 있다.
▷Safe Call 연산자 단점
- null일 때 기본값을 제공하지 않으므로, 추가 처리가 필요할 수 있다.
▶Elvis 연산자(?:)
Elvis 연산자 '?:'는 null 체크 후에 기본값을 지정할 수 있는 연산자이다. 객체가 null이면 ?: 연산자 오른쪽에 있는 값을 반환하고, null이 아니면 해당 객체의 값을 반환한다. 이를 통해 null일 때 사용할 기본값을 간단하게 지정할 수 있다.
var name: String? = null
val length = name?.length ?: 0 // name이 null이면 0 반환, 아니면 length 값 반환
println(length) // 출력: 0
→ name이 null일 경우 length에는 0이 할당된다. name이 null이 아니라면 name?.length의 값을 사용하고, null이면 0을 반환하는 방식이다. 이처럼 Elvis 연산자는 null일 경우 기본값을 간단히 지정할 수 있어 null 처리에 매우 유용하다.
▷Elvis 연산자 장점
- null일 때 대체할 값을 쉽게 지정할 수 있다.
- 코드 가독성이 좋으며, null 처리 후 기본값을 설정할 때 자주 사용된다.
▷Elvis 연산자 단점
- 기본값을 너무 남용하면, null 처리 시의 의도와 다르게 동작할 수 있어 주의가 필요하다.
▶Not-null Assertion 연산자(!!)
Not-null Assertion 연산자 '!!'는 해당 객체가 절대 null이 아님을 보장하는 경우 사용한다. 만약 이 연산자가 붙은 변수가 null이면 바로 NPE가 발생한다. 즉, 개발자가 해당 변수는 절대 null이 아님을 확신할 때 사용하는 연산자이다.
var name: String? = "Kotlin"
val length = name!!.length // name이 null이 아니라고 보장, 만약 null이면 NPE 발생
println(length) // 출력: 6
→ !! 연산자를 사용하여 name이 절대 null이 아닐 것이라고 가정하고 length() 메서드를 호출한다. 만약 name이 null이면 NPE가 발생한다. 따라서 이 연산자는 확실히 null이 아닌 경우에만 사용해야 하며, 잘못 사용하면 치명적인 예외를 일으킬 수 있다.
▷Not-null Assertion 연산자 장점
- null이 아닌 값으로 처리할 때 매우 직관적이다.
- 개발자가 null이 아님을 보장할 수 있을 때 사용하면 간결한 코드를 작성할 수 있다.
▷Not-null Assertion 연산자 단점
- 잘못 사용하면 런타임에서 NPE가 발생할 수 있다.
- 남용 시 코드의 안정성이 떨어질 수 있다.
▶세 가지 null 처리 방법의 차이점 비교
연산자 | 동작 방식 | 장점 | 단점 |
Safe Call (?.) | 객체가 null인지 체크하고, null이 아니면 메서드 호출, null이면 null 반환 | NPE 방지, 간결한 null 처리 | null일 때 기본값 제공 불가 |
Elvis 연산자 (?:) | 객체가 null이면 대체값을 반환, null이 아니면 객체의 값을 반환 | null 처리 시 기본값 제공 가능, 가독성 높음 | 남용 시 예상하지 못한 동작 발생 가능 |
Not-null Assertion (!!) | 객체가 null이 아니라고 단언, null일 경우 NPE 발생 | null이 아닌 값으로 처리할 때 직관적 | 잘못 사용하면 NPE 발생, 안전하지 않음 |
▶코틀린에서의 null 처리 방식 요약
- Safe Call 연산자는 null 가능성을 가진 변수에서 안전하게 접근할 수 있는 가장 기본적인 방법이다. NPE를 방지하고, 더 안전한 코드를 작성할 수 있다.
- Elvis 연산자는 null일 때 기본값을 제공할 수 있어 상황에 맞는 값을 제공하면서도 null 처리를 쉽게 할 수 있다.
- Not-null Assertion 연산자는 null이 아님을 보장할 수 있을 때 사용하지만, 잘못된 사용은 NPE를 유발할 수 있다. 따라서 매우 신중하게 사용해야 한다.
각각의 방법은 null을 안전하게 처리하기 위한 도구이고, 상황에 맞게 적절하게 사용해야 한다. Safe Call과 Elvis 연산자는 null 처리를 보다 간결하고 안전하게 만들어주며, Not-null Assertion은 위험성이 따르지만 확실한 상황에서는 유용하다. 코틀린은 이러한 null 안전성 기능을 통해 자바에서 흔히 발생하는 NPE를 방지하고, 더 안정적인 코드를 작성할 수 있도록 돕는다.
'Kotlin' 카테고리의 다른 글
[TIL]20241009 Extension Functions (0) | 2024.10.09 |
---|---|
[TIL]20241008 코틀린의 함수 선언 & 사용법 (0) | 2024.10.08 |
[TIL]20241006 Nullable과 Non-Nullable 타입: 코틀린의 null 안전성 (0) | 2024.10.06 |
[TIL]20241005 자바와 코틀린의 변수 선언 방식 차이 (1) | 2024.10.05 |
[TIL]20241004 var과 val 의 차이? (0) | 2024.10.04 |