본문 바로가기
기타

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

by yapdol 2024. 9. 4.

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

 

 


 

 

 

 

코틀린에 문헌 및 강의를 통해 코틀린에 대해 독학하며

학습한 내용을 정리한 글 입니다.

인프런 - [자바 개발자를 위한 코틀린 입문] 이라는 강의를 수강하며

배운 것을 그날그날 요약/정리 했습니다.

 

 


 

 

🚩 학습 컨텐츠

  • 강의명 : 인프런 - [자바 개발자를 위한 코틀린 입문]

 

 

✅ 코틀린에서 null 타입 다루는 법

코틀린에서 null이 들어갈 수 있는 타입은 완전히 다르게 취급된다.

한번 검사를 하면 non-null 임을 컴 파일러가 알 수 있다.

  1. 세이프콜 (?.) : 널이 아닌 경우에만 호출됨
  2. 엘비스 연산자 (?:)  : 널인 경우에만 호출됨
  3. 널 아님 단언 (!!) : 널이 절대 아닐 때 사용
  4. 플랫폼 타입 : 다른 프로그래밍 언어에서 전달되어서 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;
        }

    }

 

 

 

 

 

 

 

 

참고 문헌:

인프런 - [자바 개발자를 위한 코틀린 입문]