관리 메뉴

나만을 위한 블로그

[이펙티브 코틀린] 아이템 3. 최대한 플랫폼 타입을 사용하지 마라 본문

책/Effective Kotlin

[이펙티브 코틀린] 아이템 3. 최대한 플랫폼 타입을 사용하지 마라

참깨빵위에참깨빵_ 2022. 5. 8. 18:33
728x90
반응형

Null safety : 코틀린 주요 기능 중 하나. 이것으로 인해 자바에서 자주 보던 NPE는 거의 찾아보기 힘들다.

이런 매커니즘이 없는 자바, C 등의 언어와 코틀린을 연결해 사용할 땐 NPE가 발생할 수 있다. 자바에서 String을 리턴하는 메서드가 있고 코틀린에서 이걸 쓰려면 어떻게 해야 하는가?

 

@Nullable이 붙어있으면 -> nullable로 추정하고 String?으로 바꾼다

@NotNull이 붙어있으면 -> String으로 바꾼다

 

아래처럼 어노테이션이 붙어있지 않은 경우는 어떻게 해아 하는가?

 

public class JavaTest {
    public String giveName() {
        return "";
    }
}

 

자바에선 모든 것이 nullable일 수 있어서 nullable로 가정하고 다뤄야 한다.

null을 리턴하지 않을 것이 확실한 메서드는 마지막에 Not-null 단정을 나타내는 !!를 붙인다.

 

nullable과 관련해서 자주 문제되는 부분은 자바의 제네릭 타입이다. 자바 API에서 List<User>를 리턴하고 어노테이션이 없는 경우 코틀린이 디폴트로 모든 타입을 nullable로 다룬다면 개발자는 이걸 쓸 때 이러한 리스트와 리스트 내부의 User 객체들이 null이 아니란 걸 알아야 한다. 따라서 리스트 자체만 null인지 확인해선 안 되고 그 내부의 것들도 null인지 확인해야 한다.

 

리스트는 적어도 map, filterNotNull() 등의 메서드를 제공한다. 다른 제네릭 타입이라면 null 확인 자체가 정말 복잡한 일이 된다.

그래서 코틀린은 자바 등 다른 언어에서 넘어온 타입들을 특수하게 다룬다. 이런 타입을 플랫폼 타입이라 부른다.

플랫폼 타입은 String!처럼 타입이름 뒤에 !를 붙여 표기한다. 이런 어노테이션이 직접적으로 코드에 나타나진 않는다.

 

자바를 코틀린과 같이 쓸 때 자바 코드를 직접 조작할 수 있다면 가능한 @Nullable, @NotNull을 붙여서 사용하라.

 

저자 개인적으로 플랫폼 타입은 안전하지 않으므로 최대한 빨리 제거하는 게 좋다고 생각한다. 아래 코드로 예시를 든다.

 

// 자바
public String getValue() {
    return null;
}

// 코틀린
fun statedType() {
    val value: String = JavaClass().value   // NPE
    // ...
    println(value.length)
}

fun platformType() {
    val value = JavaClass().value
    // ...
    println(value.lenghth)  // NPE
}

 

statedType에선 자바에서 값을 가져오는 위치에서 NPE가 발생한다. 이 경우 null이 나온다는 걸 굉장히 쉽게 알 수 있어 코드를 쉽게 수정할 수 있다.

platformType에선 값을 활용할 때 NPE가 발생한다. 플랫폼 타입으로 지정된 변수는 nullable일 수 있고 아닐 수도 있다. 이런 변수를 한두 번 안전하게 썼더라도 이후에 다른 사람이 쓸 때는 NPE를 발생시킬 가능성이 존재한다. 객체를 쓴다고 NPE가 발생될 거라 생각하지 않으므로 오류 찾는 데 오랜 시간이 걸릴 것이다.

 

이처럼 플랫폼 타입은 항상 위험을 내포하고 있으므로 안전한 코드를 원한다면 이런 부분을 제거하는 게 좋다.

반응형
Comments