• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

안녕하세요 null 에 관해 질문 드리고 싶은게 있습니다.

22.08.21 01:13 작성 조회수 227

1

안녕하세요 강의 잘듣고 있습니다.

null 관련하여 궁금한게 있어서 질문 남깁니다.

?. 을 붙여주면 null을 다룰 수 있는 걸로 알고 있습니다.

만약 그렇다면 @notnull, @nullable 을 java 에서 사용하지 않는다는 가정하에

1. assertThat(result[0]?.age).isEqualTo(request?.age)

2. assertThat(result[0]?.age).isNull()

에서 1에 값은 NPE 가 뜨고 2에 서는 NPE 가 안뜨는 이유가 궁금 합니다.

println("result[0]?.age = ${result[0]?.age}")

println("result[0].age = ${result[0].age}")

println("request?.age = ${request?.age}")

println("request.age = ${request.age}")

위 4개의 코드에서는 전부 null 을 반환하여 질문하게 되었습니다.

읽어주셔서 감사합니다.

 

답변 1

답변을 작성해보세요.

1

안녕하세요 경재님!! 아~ 너무너무 좋은 질문이십니다!! ㅎㅎㅎㅎ 😊

 

말씀해주신 첫 번째 코드를 살펴보았는데요!! NPE는 

1. assertThat(result[0]?.age).isEqualTo(request?.age)

부분 중, "request?.age" 에서 나고 있었습니다!!

 

경재님의 궁금증은 이 부분이신 것 같아요! 오잉~ 코틀린에서 ?. 를 사용하면 null처리를 잘 해주는 것 아닌가?!

 

네네 그 사실은 맞습니다! 다만, 현재 request.age 자체가 플랫폼 타입이라는 것이 문제입니다!! 😢

request 자체가 Java의 객체이고, age를 가져올 때 Java Integer 타입을 코틀린 쪽으로 가져오게 되는데 이렇게 되면 코틀린은 이를 'Int! 타입 (=정수인데 null일수도 있고 null이 아닐 수도 있는 플랫폼타입)'으로 인지하게 되고, safe call은 Int! 타입이 아닌, Int? 타입 (코틀린은 둘을 완전히 다른 타입으로 간주하게 됩니다!) 에만 올바르게 동작하다 보니, Int! 타입에 대해서는 정상동작하지 않게 됩니다!!

 

실제로 적어주신 코드를 Decompile해보면 request.getAge() 를 사용해 null이 아니라고 단정해버리는 코드를 확인하실 수 있습니다!!

 

이를 해결하기 위해서는, UserCreateRequest 객체에 적절한 @Nullable 어노테이션을 사용해주시면,  request.age는 Int!가 아니라 Int?가 되고, 적어주신 첫 번째 코드는 정상 동작하게 됩니다!!

 

요약드리면 이렇습니다 ㅎㅎㅎ

1. 플랫폼 타입은 코틀린에서 완전히 다르게 적용되어 Safe Call 자체가 동작하지 않는다

2. 때문에 1번, request.getAge()에서 에러가 나게 되었다.

 

혹시나 더 궁금한 점 있으시다면 편하게 질문 더 남겨주세요!!!

감사합니다 ㅎㅎㅎㅎ 행복한 주말 되세요~!!