[Kotlin] 코틀린에서 null 타입 다루는 법 : 자바 vs 코틀린 코드 비교/세이프콜/엘비스연산자/널아님단언!!/플랫폼타입

코틀린에 문헌 및 강의를 통해 코틀린에 대해 독학하며
학습한 내용을 정리한 글 입니다.
인프런 - [자바 개발자를 위한 코틀린 입문] 이라는 강의를 수강하며
배운 것을 그날그날 요약/정리 했습니다.
🚩 학습 컨텐츠
- 강의명 : 인프런 - [자바 개발자를 위한 코틀린 입문]
✅ 코틀린에서 null 타입 다루는 법
코틀린에서 null이 들어갈 수 있는 타입은 완전히 다르게 취급된다.
한번 검사를 하면 non-null 임을 컴 파일러가 알 수 있다.
- 세이프콜 (?.) : 널이 아닌 경우에만 호출됨
- 엘비스 연산자 (?:) : 널인 경우에만 호출됨
- 널 아님 단언 (!!) : 널이 절대 아닐 때 사용
- 플랫폼 타입 : 다른 프로그래밍 언어에서 전달되어서 nullable인지 아닌지 알 수 없는 타입. 코틀린에서 자바 코드를 사용할 때 플랫폼 타입에 사용해 유의해야 한다. 자바 코드를 읽으며 널일 가능성을 꼼꼼히 확인하면 좋다.
✅ 자바 vs 코틀린 코드 비교
A로 시작하는지 아닌지 확인하는 함수 startsWith를 예시를 보자.
⭐예제 1
1-1. 자바코드
boolean 은 원시(프리미티브)타입이기 때문에 null 이 들어갈 수 없음.
public boolean startsWithA1(String str) {
if (str == null) {
throw new IllegalArgumentException("null이 들어왔습니다");
}
return str.startsWith("A");
}
1-2 .코틀린 코드로 변경
따라서 코틀린코드로 변형시, Boolean 에 물음표를 붙이지 않음.
fun startsWithA1(str: String?): Boolean {
if(str == null) {
throw IllegalArgumentException("null이 들어왔습니다");
}
return str.startsWith("A")
}
1-3.세이프콜 & 엘비스연산자 사용해 변경
null 일 수도 있는 str 변수가 들어가면
null 이 아닌 경우 startsWith 호출해서 그 결과를 반환
null 경우 익셉션을 던지라는 뜻
세이프 콜과 엘비스 연산자를 사용해 이프문을 쓰지 않아 코드가 더 간결해짐
fun startsWithA1(str: String?): Boolean {
str?.startsWith("A") ?: throw IllegalArgumentException("null이 들어왔습니다")
}
⭐예제 2
2-1. 자바코드
Boolean 은 참조(레퍼런스)타입이기 때문에 null 이 들어갈 수 있음.
public Boolean startsWith2(String str) {
if(str == null) {
return null;
}
return str.startsWith("A");
}
2-2 .코틀린 코드로 변경
따라서 코틀린코드로 변형시, Boolean 에 ?를 붙임.
fun startsWith2(str : String?): Boolean? {
if(str == null) {
return null;
}
return str.startsWith("A")
}
2-3. if문 대신, 코틀린의 세이프콜 & 엘비스연산자를 사용
세이프콜은 앞의 변수가 null이면 그대로 null이 된다.
따라서 A를 호출한 다음에 그냥 리턴해 주면 됨.
왜냐면 두 번째 함수는 null일 경우 그냥 null를 반환하기 때문
그래서이 코드는 str이 null이면 전체가 null이 될거고 널이 아니면 결과가 반환될 것임.
fun startsWith2(str: String?): Boolean? {
str.?startsWith("A")
}
⭐예제 3
3-1. 자바코드
public boolean startsWith3(String str) {
if (str == null) {
return false;
}
return str.startsWith("A");
}
3-2 .코틀린 코드로 변경
fun startsWith3(str: String?): Boolean {
if(str == null) {
return false;
}
return str.startsWith("A");
}
3-3. if문 대신, 코틀린의 세이프콜 & 엘비스연산자를 사용
fun startsWith3(str:String?): Boolean {
str.?startsWith("A") :? false
}
✅ 널 아님 단언 : !!
nullabe 타입이지만 아무리 생각해도 될 수 없는 경우가 있다.
보통 코딩을 하다 보면 DB에 맨 처음 데이터가 들어갈 땐 널이였다가
한번 어떤 업데이트가 있고 난 후에는 절대 널이 될 수 없는 필드들이 있다.
그런데 그게 들어갈 때도 널일수도 있다 보니까 엔티티를 설계할 때 nullabe 필드로 쓸 수 밖에 없는 경우가 있는데
그런 경우 매번 세이프콜를 꺼내서 그때마다 계속 쓰고 그때그때마다 널에 대한 예외 처리를 계속해줄 순 없으니까
얘는 무조건 널이 아니야라는 신호가 필요할 수 있다. 그 신호를!!로 사용한다.
- 널이 들어갈 경우 널포인트익셉션 발생
fun startsWith(str:String?): Boolean {
str.!!startsWith("A")
}
✅ 플랫폼타입
: 다른 프로그래밍 언어에서 전달되어서 nullable인지 아닌지 알 수 없는 타입.
코틀린과 자바는 100% 호환 가능한 언어이다 병행해서 쓰는 경우가 많다.
그러다보니 한 프로젝트 내에서 코틀린에서 자바코드를 같이 사용했 때 오류가 발생할 수 있다.
코틀린에서 자바 코드를 사용할 때 플랫폼 타입에 사용해 유의해야 한다. 자바 코드를 읽으며 널일 가능성을 꼼꼼히 확인하면 좋다.
@nullabe 인지 @notnull 인지 주석 처리 되어있지 않기때문에,
코틀린에서 호출하여 사용할 경우 런타임에서 널타입익셉션 오류가 발생함.
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
// @nullabe 인지 @notnull 인지 주석 처리 되어있지 않기때문에,
// 코틀린에서 호출하여 사용할 경우 런타임에서 널타입익셉션 오류가 발생함.
public String getName() {
return name;
}
}
참고 문헌:
인프런 - [자바 개발자를 위한 코틀린 입문]